This is commit of Simon Detheridge's pull request "osx-opencl" with a few modifications.

-If we change OpenCLWrapper to capture build log errors, we don't need to manually concat them in RendererCL because the overridden ErrorReport() function already concatenates the errors from both classes.

-Do not define T in OpenCL programs. We already have real_t to handle this.

-Do keep the casting to real_t. However this should not be necessary because there is a command line option to do this automatically which we already use: -cl-single-precision-constant. The only reason we do this is because the Apple OpenCL compiler does not follow the standard and obviously ignores this option. Absolutely awful.

-Fix a few improper casts in the CircleTrans1 and GlynnSim1 variations.

-Add an automated OpenCL program build tester to EmberTester, as well as a cast checker.
This commit is contained in:
mfeemster 2015-03-22 12:46:10 -07:00
parent fa6ec63447
commit ef01380e6d
8 changed files with 193 additions and 126 deletions

View File

@ -2096,8 +2096,8 @@ protected:
m_Params.clear(); m_Params.clear();
m_Params.push_back(ParamWithName<T>(&m_Slices, prefix + "pie_slices", 6, INTEGER_NONZERO, 1)); m_Params.push_back(ParamWithName<T>(&m_Slices, prefix + "pie_slices", 6, INTEGER_NONZERO, 1));
m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "pie_rotation", T(0.5), REAL_CYCLIC, 0, M_2PI)); m_Params.push_back(ParamWithName<T>(&m_Rotation, prefix + "pie_rotation", T(0.5), REAL_CYCLIC, 0, M_2PI));
m_Params.push_back(ParamWithName<T>(&m_Thickness, prefix + "pie_thickness", T(0.5), REAL, 0, 1)); m_Params.push_back(ParamWithName<T>(&m_Thickness, prefix + "pie_thickness", T(0.5), REAL, 0, 1));
} }
private: private:

View File

@ -528,7 +528,7 @@ public:
return return
"void GlynnSim1Circle(__constant real_t* radius1, __constant real_t* thickness, __constant real_t* x1, __constant real_t* y1, uint2* mwc, real_t* x, real_t* y)\n" "void GlynnSim1Circle(__constant real_t* radius1, __constant real_t* thickness, __constant real_t* x1, __constant real_t* y1, uint2* mwc, real_t* x, real_t* y)\n"
"{\n" "{\n"
" real_t r = *radius1 * (*thickness + (T(1.0) - *thickness) * MwcNext01(mwc));\n" " real_t r = *radius1 * (*thickness + ((real_t)(1.0) - *thickness) * MwcNext01(mwc));\n"
" real_t phi = M_2PI * MwcNext01(mwc);\n" " real_t phi = M_2PI * MwcNext01(mwc);\n"
" real_t sinPhi = sin(phi);\n" " real_t sinPhi = sin(phi);\n"
" real_t cosPhi = cos(phi);\n" " real_t cosPhi = cos(phi);\n"

View File

@ -485,8 +485,8 @@ public:
"\n" "\n"
"void CircleTrans1Trans(real_t a, real_t b, real_t x, real_t y, real_t* x1, real_t* y1)\n" "void CircleTrans1Trans(real_t a, real_t b, real_t x, real_t y, real_t* x1, real_t* y1)\n"
"{\n" "{\n"
" *x1 = (x - a) * T(0.5) + a;\n" " *x1 = (x - a) * (real_t)(0.5) + a;\n"
" *y1 = (y - b) * T(0.5) + b;\n" " *y1 = (y - b) * (real_t)(0.5) + b;\n"
"}\n" "}\n"
"\n" "\n"
"void CircleTrans1CircleR(real_t mx, real_t my, real_t sc, real_t seed, real_t dens, real_t* ux, real_t* vy, uint2* mwc)\n" "void CircleTrans1CircleR(real_t mx, real_t my, real_t sc, real_t seed, real_t dens, real_t* ux, real_t* vy, uint2* mwc)\n"
@ -498,10 +498,10 @@ public:
" {\n" " {\n"
" x = fabs(mx) * (1 - 2 * MwcNext01(mwc));\n" " x = fabs(mx) * (1 - 2 * MwcNext01(mwc));\n"
" y = fabs(my) * (1 - 2 * MwcNext01(mwc));\n" " y = fabs(my) * (1 - 2 * MwcNext01(mwc));\n"
" m = (int)floor(T(0.5) * x / sc);\n" " m = (int)floor((real_t)(0.5) * x / sc);\n"
" n = (int)floor(T(0.5) * y / sc);\n" " n = (int)floor((real_t)(0.5) * y / sc);\n"
" alpha = M_2PI * MwcNext01(mwc);\n" " alpha = M_2PI * MwcNext01(mwc);\n"
" u = T(0.3) + T(0.7) * CircleTrans1DiscreteNoise2(m + 10, n + 3);\n" " u = (real_t)(0.3) + (real_t)(0.7) * CircleTrans1DiscreteNoise2(m + 10, n + 3);\n"
" x = u * cos(alpha);\n" " x = u * cos(alpha);\n"
" y = u * sin(alpha);\n" " y = u * sin(alpha);\n"
"\n" "\n"

View File

@ -1130,7 +1130,6 @@ uint OpenCLWrapper::DeviceIndex() const { return m_DeviceIndex; }
size_t OpenCLWrapper::GlobalMemSize() const { return GetInfo<cl_ulong>(PlatformIndex(), DeviceIndex(), CL_DEVICE_GLOBAL_MEM_SIZE); } size_t OpenCLWrapper::GlobalMemSize() const { return GetInfo<cl_ulong>(PlatformIndex(), DeviceIndex(), CL_DEVICE_GLOBAL_MEM_SIZE); }
uint OpenCLWrapper::LocalMemSize() const { return m_LocalMemSize; } uint OpenCLWrapper::LocalMemSize() const { return m_LocalMemSize; }
size_t OpenCLWrapper::MaxAllocSize() const { return GetInfo<cl_ulong>(PlatformIndex(), DeviceIndex(), CL_DEVICE_MAX_MEM_ALLOC_SIZE); } size_t OpenCLWrapper::MaxAllocSize() const { return GetInfo<cl_ulong>(PlatformIndex(), DeviceIndex(), CL_DEVICE_MAX_MEM_ALLOC_SIZE); }
std::vector<std::string> OpenCLWrapper::ProgramBuildErrors() const { return m_programBuildErrors; }
/// <summary> /// <summary>
/// Makes the even grid dims. /// Makes the even grid dims.
@ -1243,9 +1242,11 @@ bool OpenCLWrapper::CreateSPK(const string& name, const string& program, const s
if (CheckCL(err, "cl::Kernel()")) if (CheckCL(err, "cl::Kernel()"))
return true;//Everything is ok. return true;//Everything is ok.
} else { }
for (std::vector<cl::Device>::iterator i = m_DeviceVec.begin(); i != m_DeviceVec.end(); ++ i ) else
m_programBuildErrors.push_back(spk.m_Program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(*i)); {
for (auto& i : m_DeviceVec)
m_ErrorReport.push_back(spk.m_Program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(i));
} }
} }

View File

@ -218,6 +218,5 @@ private:
std::vector<NamedBuffer> m_Buffers; std::vector<NamedBuffer> m_Buffers;
std::vector<NamedImage2D> m_Images; std::vector<NamedImage2D> m_Images;
std::vector<NamedImage2DGL> m_GLImages; std::vector<NamedImage2DGL> m_GLImages;
std::vector<std::string> m_programBuildErrors;
}; };
} }

View File

@ -501,8 +501,8 @@ string RendererCL<T>::ErrorReportString()
template <typename T> template <typename T>
vector<string> RendererCL<T>::ErrorReport() vector<string> RendererCL<T>::ErrorReport()
{ {
vector<string> ours = EmberReport::ErrorReport(); auto ours = EmberReport::ErrorReport();
vector<string> wrappers = m_Wrapper.ErrorReport(); auto wrappers = m_Wrapper.ErrorReport();
ours.insert(ours.end(), wrappers.begin(), wrappers.end()); ours.insert(ours.end(), wrappers.begin(), wrappers.end());
return ours; return ours;
@ -759,12 +759,7 @@ bool RendererCL<T>::BuildIterProgramForEmber(bool doAccum)
} }
else else
{ {
//m_ErrorReport.push_back(string(loc) + "():\nBuilding the following program failed: \n" + m_IterKernel + "\n"); m_ErrorReport.push_back(string(loc) + "():\nBuilding the following program failed: \n" + m_IterKernel + "\n");
std::vector<std::string> errors = m_Wrapper.ProgramBuildErrors();
m_ErrorReport.insert(m_ErrorReport.end(), errors.begin(), errors.end());
m_ErrorReport.push_back(loc);
return false; return false;
} }
@ -1272,7 +1267,6 @@ int RendererCL<T>::MakeAndGetDensityFilterProgram(size_t ss, uint filterWidth)
else else
{ {
m_ErrorReport.push_back(string(loc) + "():\nBuilding the following program failed: \n" + kernel + "\n"); m_ErrorReport.push_back(string(loc) + "():\nBuilding the following program failed: \n" + kernel + "\n");
//cout << m_ErrorReport.back();
} }
} }
@ -1302,11 +1296,7 @@ int RendererCL<T>::MakeAndGetFinalAccumProgram(T& alphaBase, T& alphaScale)
if (b) if (b)
kernelIndex = m_Wrapper.FindKernelIndex(finalAccumEntryPoint);//Try to find it again, it will be present if successfully built. kernelIndex = m_Wrapper.FindKernelIndex(finalAccumEntryPoint);//Try to find it again, it will be present if successfully built.
else else
{
std::vector<std::string> errors = m_Wrapper.ProgramBuildErrors();
m_ErrorReport.insert(m_ErrorReport.end(), errors.begin(), errors.end());
m_ErrorReport.push_back(loc); m_ErrorReport.push_back(loc);
}
} }
return kernelIndex; return kernelIndex;

View File

@ -155,7 +155,9 @@ protected:
virtual eRenderStatus AccumulatorToFinalImage(byte* pixels, size_t finalOffset) override; virtual eRenderStatus AccumulatorToFinalImage(byte* pixels, size_t finalOffset) override;
virtual EmberStats Iterate(size_t iterCount, size_t temporalSample) override; virtual EmberStats Iterate(size_t iterCount, size_t temporalSample) override;
#ifndef TEST_CL
private: private:
#endif
//Private functions for making and running OpenCL programs. //Private functions for making and running OpenCL programs.
bool BuildIterProgramForEmber(bool doAccum = true); bool BuildIterProgramForEmber(bool doAccum = true);
bool RunIter(size_t iterCount, size_t temporalSample, size_t& itersRan); bool RunIter(size_t iterCount, size_t temporalSample, size_t& itersRan);

View File

@ -13,7 +13,6 @@
/// </summary> /// </summary>
using namespace EmberNs; using namespace EmberNs;
//#define TEST_CL 1
template <typename T> template <typename T>
void SaveFinalImage(Renderer<T, T>& renderer, vector<byte>& pixels, char* suffix) void SaveFinalImage(Renderer<T, T>& renderer, vector<byte>& pixels, char* suffix)
@ -94,33 +93,32 @@ string GetEmberCLKernelString(Ember<float>& ember, bool iter, bool log, bool de,
return os.str(); return os.str();
} }
void MakeTestAllVarsRegPrePostComboFile(const string& filename) template <typename T>
void MakeTestAllVarsRegPrePost(vector<Ember<T>>& embers)
{ {
EmberToXml<float> writer;
vector<Ember<float>> embers;
VariationList<float> varList;
uint index = 0; uint index = 0;
PaletteList<float> paletteList;
ostringstream ss; ostringstream ss;
VariationList<T> varList;
PaletteList<T> paletteList;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
paletteList.Init("flam3-palettes.xml"); paletteList.Init("flam3-palettes.xml");
Timing t; Timing t;
Ember<float> emberNoVars; Ember<T> emberNoVars;
emberNoVars.m_FinalRasW = 640; emberNoVars.m_FinalRasW = 640;
emberNoVars.m_FinalRasH = 480; emberNoVars.m_FinalRasH = 480;
emberNoVars.m_Quality = 100; emberNoVars.m_Quality = 100;
Xform<float> xform1(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform1(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform2(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform2(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform3(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform3(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform4(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform4(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform5(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform5(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform6(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform6(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform7(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform7(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
emberNoVars.AddXform(xform1); emberNoVars.AddXform(xform1);
emberNoVars.AddXform(xform2); emberNoVars.AddXform(xform2);
@ -138,22 +136,22 @@ void MakeTestAllVarsRegPrePostComboFile(const string& filename)
while (index < varList.RegSize()) while (index < varList.RegSize())
{ {
Ember<float> ember1; Ember<T> ember1;
unique_ptr<Variation<float>> regVar(varList.GetVariationCopy(index, VARTYPE_REG)); unique_ptr<Variation<T>> regVar(varList.GetVariationCopy(index, VARTYPE_REG));
unique_ptr<Variation<float>> preVar(varList.GetVariationCopy("pre_" + regVar->Name())); unique_ptr<Variation<T>> preVar(varList.GetVariationCopy("pre_" + regVar->Name()));
unique_ptr<Variation<float>> postVar(varList.GetVariationCopy("post_" + regVar->Name())); unique_ptr<Variation<T>> postVar(varList.GetVariationCopy("post_" + regVar->Name()));
ember1.m_FinalRasW = 640; ember1.m_FinalRasW = 640;
ember1.m_FinalRasH = 480; ember1.m_FinalRasH = 480;
ember1.m_Quality = 100; ember1.m_Quality = 100;
Xform<float> xform1(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform1(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform2(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform2(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform3(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform3(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform4(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform4(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform5(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform5(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform6(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform6(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
Xform<float> xform7(0.25f, rand.Frand01<float>(), rand.Frand11<float>(), 1, rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>(), rand.Frand11<float>()); Xform<T> xform7(0.25f, rand.Frand01<T>(), rand.Frand11<T>(), 1, rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>(), rand.Frand11<T>());
if (preVar.get() && postVar.get()) if (preVar.get() && postVar.get())
{ {
@ -204,7 +202,14 @@ void MakeTestAllVarsRegPrePostComboFile(const string& filename)
} }
t.Toc("Creating embers for all possible variations"); t.Toc("Creating embers for all possible variations");
}
void MakeTestAllVarsRegPrePostComboFile(const string& filename)
{
EmberToXml<float> writer;
vector<Ember<float>> embers;
MakeTestAllVarsRegPrePost(embers);
writer.Save(filename, embers, 0, true, false, true); writer.Save(filename, embers, 0, true, false, true);
} }
@ -320,7 +325,7 @@ bool SearchVar(Variation<T>* var, vector<string>& stringVec, bool matchAll)
{ {
bool ret = false; bool ret = false;
size_t i; size_t i;
string cl = var->OpenCLString(); auto cl = var->OpenCLFuncsString() + "\n" + var->OpenCLString();
if (matchAll) if (matchAll)
{ {
@ -1315,6 +1320,33 @@ void TestVarTime()
//ForEach(times, [&](pair<string, double>& p) { cout << p.first << "\t" << p.second << "" << endl; }); //ForEach(times, [&](pair<string, double>& p) { cout << p.first << "\t" << p.second << "" << endl; });
} }
void TestCasting()
{
vector<string> stringVec;
vector<Variation<float>*> varVec;
stringVec.push_back("T(");
stringVec.push_back(".0f");
stringVec.push_back(".1f");
stringVec.push_back(".2f");
stringVec.push_back(".3f");
stringVec.push_back(".4f");
stringVec.push_back(".5f");
stringVec.push_back(".6f");
stringVec.push_back(".7f");
stringVec.push_back(".8f");
stringVec.push_back(".9f");
varVec = FindVarsWith<float>(stringVec);
for (auto& it : varVec)
{
cout << "Variation " << it->Name() << " contained an improper float cast." << endl;
}
ClearVec<Variation<float>>(varVec);
}
template <typename T> template <typename T>
void TestOperations() void TestOperations()
{ {
@ -1472,6 +1504,37 @@ void TestVarsSimilar()
} }
#ifdef TEST_CL #ifdef TEST_CL
template <typename T>
void TestAllVarsCLBuild(bool printSuccess = true)
{
vector<Ember<T>> embers;
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
RendererCL<T> renderer;
const char* loc = __FUNCTION__;
if (!renderer.Init(1, 0, false, 0))
{
cout << loc << "Creating RendererCL failed, tests will not be run." << endl;
return;
}
MakeTestAllVarsRegPrePost(embers);
for (auto& it : embers)
{
renderer.SetEmber(it);
if (renderer.BuildIterProgramForEmber())
{
if (printSuccess)
cout << loc << ": Build succeeded for ember " << it.m_Name << endl;
}
else
cout << loc << ": OpenCL program build failed:\n" << renderer.ErrorReport() << endl;
}
}
template <typename T> template <typename T>
void TestCpuGpuResults() void TestCpuGpuResults()
{ {
@ -1747,85 +1810,85 @@ double RandD(QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand)
{ {
return ((((rand.Rand()^(rand.Rand()<<15))&0xfffffff)*3.72529e-09)-0.5); return ((((rand.Rand()^(rand.Rand()<<15))&0xfffffff)*3.72529e-09)-0.5);
} }
//
#define BEZ_POINT_LENGTH 4 //#define BEZ_POINT_LENGTH 4
//
void BezierSolve(double t, glm::vec2* src, double* w, glm::vec2& solution) //void BezierSolve(double t, glm::vec2* src, double* w, glm::vec2& solution)
{ //{
double s, s2, s3, t2, t3, nom_x, nom_y, denom; // double s, s2, s3, t2, t3, nom_x, nom_y, denom;
//
s = 1 - t; // s = 1 - t;
s2 = s * s; // s2 = s * s;
s3 = s * s * s; // s3 = s * s * s;
t2 = t * t; // t2 = t * t;
t3 = t * t * t; // t3 = t * t * t;
//
nom_x = w[0] * s3 * src[0].x + w[1] * s2 * 3 * t * src[1].x + w[2] * s * 3 * t2 * src[2].x + w[3] * t3 * src[3].x; // nom_x = w[0] * s3 * src[0].x + w[1] * s2 * 3 * t * src[1].x + w[2] * s * 3 * t2 * src[2].x + w[3] * t3 * src[3].x;
//
nom_y = w[0] * s3 * src[0].y + w[1] * s2 * 3 * t * src[1].y + w[2] * s * 3 * t2 * src[2].y + w[3] * t3 * src[3].y; // nom_y = w[0] * s3 * src[0].y + w[1] * s2 * 3 * t * src[1].y + w[2] * s * 3 * t2 * src[2].y + w[3] * t3 * src[3].y;
//
denom = w[0] * s3 + w[1] * s2 * 3 * t + w[2] * s * 3 * t2 + w[3] * t3; // denom = w[0] * s3 + w[1] * s2 * 3 * t + w[2] * s * 3 * t2 + w[3] * t3;
//
//
if (isnan(nom_x) || isnan(nom_y) || isnan(denom) || denom == 0) // if (isnan(nom_x) || isnan(nom_y) || isnan(denom) || denom == 0)
return; // return;
//
solution.x = nom_x / denom; // solution.x = nom_x / denom;
solution.y = nom_y / denom; // solution.y = nom_y / denom;
} //}
//
void BezierSetRect(glm::vec2* points, bool flip, glm::vec4& rect) //void BezierSetRect(glm::vec2* points, bool flip, glm::vec4& rect)
{ //{
double f; // double f;
//
for (int i = 0; i < BEZ_POINT_LENGTH; i++) // for (int i = 0; i < BEZ_POINT_LENGTH; i++)
{ // {
if (flip) // if (flip)
f = 1 - points[i].y; // f = 1 - points[i].y;
else // else
f = points[i].y; // f = points[i].y;
//
points[i].x = points[i].x * (rect.z - rect.x) + rect.x; // points[i].x = points[i].x * (rect.z - rect.x) + rect.x;
points[i].y = f * (rect.w - rect.y) + rect.y; // points[i].y = f * (rect.w - rect.y) + rect.y;
} // }
} //}
//
void BezierUnsetRect(glm::vec2* points, bool flip, glm::vec4& rect) //void BezierUnsetRect(glm::vec2* points, bool flip, glm::vec4& rect)
{ //{
if ((rect.z - rect.x) == 0 || (rect.w - rect.y) == 0) // if ((rect.z - rect.x) == 0 || (rect.w - rect.y) == 0)
return; // return;
//
for (int i = 0; i < BEZ_POINT_LENGTH; i++) // for (int i = 0; i < BEZ_POINT_LENGTH; i++)
{ // {
points[i].x = (points[i].x - rect.x) / (rect.z - rect.x); // points[i].x = (points[i].x - rect.x) / (rect.z - rect.x);
points[i].y = (points[i].y - rect.y) / (rect.w - rect.y); // points[i].y = (points[i].y - rect.y) / (rect.w - rect.y);
//
if (flip) // if (flip)
points[i].y = 1 - points[i].y; // points[i].y = 1 - points[i].y;
} // }
} //}
//
struct BezierPoints //struct BezierPoints
{ //{
glm::vec2 points[4]; // glm::vec2 points[4];
}; //};
//
struct BezierWeights //struct BezierWeights
{ //{
double points[4]; // double points[4];
}; //};
int _tmain(int argc, _TCHAR* argv[]) int _tmain(int argc, _TCHAR* argv[])
{ {
//int i; //int i;
Timing t(4); Timing t(4);
QTIsaac<ISAAC_SIZE, ISAAC_INT> rand; QTIsaac<ISAAC_SIZE, ISAAC_INT> rand;
glm::vec2 solution, src[4]; //glm::vec2 solution, src[4];
double bezT = 1, w[4]; //double bezT = 1, w[4];
BezierPoints curvePoints[4]; //BezierPoints curvePoints[4];
BezierWeights curveWeights[4]; //BezierWeights curveWeights[4];
//
BezierSolve(bezT, src, w, solution); //BezierSolve(bezT, src, w, solution);
//cout << pow(-1, 5.1) << endl; //cout << pow(-1, 5.1) << endl;
@ -1894,6 +1957,10 @@ int _tmain(int argc, _TCHAR* argv[])
//cd2 = sin(cd); //cd2 = sin(cd);
/* /*
t.Tic();
TestCasting();
t.Toc("TestCasting()");
t.Tic(); t.Tic();
VariationList<float> vlf; VariationList<float> vlf;
t.Toc("Creating VariationList<float>"); t.Toc("Creating VariationList<float>");
@ -1990,10 +2057,18 @@ int _tmain(int argc, _TCHAR* argv[])
//TestCpuGpuResults<float>(); //TestCpuGpuResults<float>();
//t.Toc("TestCpuGpuResults<float>()"); //t.Toc("TestCpuGpuResults<float>()");
t.Tic();
TestAllVarsCLBuild<float>();
t.Toc("TestAllVarsCLBuild<float>()");
#ifdef DO_DOUBLE #ifdef DO_DOUBLE
//t.Tic(); //t.Tic();
//TestCpuGpuResults<double>(); //TestCpuGpuResults<double>();
//t.Toc("TestCpuGpuResults<double>()"); //t.Toc("TestCpuGpuResults<double>()");
t.Tic();
TestAllVarsCLBuild<double>();
t.Toc("TestAllVarsCLBuild<double>()");
#endif #endif
#endif #endif