Features:

--Added panorama1 and panorama2 variations.

Bug fixes:
--crackle had a bug with Nvidia GPUs.

Code changes:
--crackle now uses real_t* for cache rather than real2. This is what was causing the bug.
--Make the local offsets array used in crackle a precalc since it's the same for all. This reduces register pressure.
--Get rid of all usages of real3, just to be safe since Nvidia doesn't like them.
--#define TOTAL_GLOBAL_SIZE_END in the OpenCL iteration kernel just for debugging purposes to see how large the parvars buffer is.
This commit is contained in:
Person 2017-08-16 17:33:11 -07:00
parent d6d121ac95
commit 59f5bffc3c
8 changed files with 142 additions and 28 deletions

View File

@ -259,14 +259,13 @@ public:
v3T c[4]; // Co-ordinates of four simplex shape corners in (x,y,z)
T n = 0; // Noise total value
int gi[4]; // Hashed grid index for each corner, used to determine gradient
T t; // Temp double
// Convert input co-ordinates ( x, y, z ) to
// integer-based simplex grid ( i, j, k )
T skewIn = (v.x + v.y + v.z) * T(0.333333);
intmax_t i = Floor<T>(v.x + skewIn);
intmax_t j = Floor<T>(v.y + skewIn);
intmax_t k = Floor<T>(v.z + skewIn);
t = (i + j + k) * T(0.1666666);
T t = (i + j + k) * T(0.1666666);
// Cell origin co-ordinates in input space (x,y,z)
T x0 = i - t;
T y0 = j - t;
@ -552,8 +551,10 @@ private:
{
m_P = InitInts();
m_Grad = InitGrad();
m_Offsets = InitOffsets();
m_GlobalMap["NOISE_INDEX"] = make_pair(m_PFloats.data(), m_PFloats.size());
m_GlobalMap["NOISE_POINTS"] = make_pair(static_cast<T*>(&(m_Grad[0].x)), SizeOf(m_Grad) / sizeof(T));
m_GlobalMap["OFFSETS"] = make_pair(static_cast<T*>(&(m_Offsets[0].x)), SizeOf(m_Offsets) / sizeof(T));
}
/// <summary>
@ -962,8 +963,24 @@ private:
return g;
}
/// <summary>
/// Initializes the offsets used in the crackle variation.
/// </summary>
/// <returns>A copy of the locally declared vector</returns>
std::vector<v2T> InitOffsets()
{
std::vector<v2T> g =
{
{ -1, -1 }, { -1, 0 }, { -1, 1 },
{ 0, -1 }, { 0, 0 }, { 0, 1 },
{ 1, -1 }, { 1, 0 }, { 1, 1 }
};
return g;
}
std::vector<int> m_P;
std::vector<T> m_PFloats;
std::vector<v2T> m_Offsets;
std::vector<v3T> m_Grad;
std::unordered_map<string, pair<const T*, size_t>> m_GlobalMap;
};

View File

@ -251,6 +251,8 @@ enum class eVariationId : et
VAR_OSCILLOSCOPE,
VAR_OVOID ,
VAR_OVOID3D ,
VAR_PANORAMA1 ,
VAR_PANORAMA2 ,
VAR_PARABOLA ,
VAR_PDJ ,
VAR_PERSPECTIVE ,
@ -580,6 +582,8 @@ enum class eVariationId : et
VAR_PRE_OSCILLOSCOPE,
VAR_PRE_OVOID,
VAR_PRE_OVOID3D,
VAR_PRE_PANORAMA1,
VAR_PRE_PANORAMA2,
VAR_PRE_PARABOLA,
VAR_PRE_PDJ,
VAR_PRE_PERSPECTIVE,
@ -909,6 +913,8 @@ enum class eVariationId : et
VAR_POST_OSCILLOSCOPE,
VAR_POST_OVOID,
VAR_POST_OVOID3D,
VAR_POST_PANORAMA1,
VAR_POST_PANORAMA2,
VAR_POST_PARABOLA,
VAR_POST_PDJ,
VAR_POST_PERSPECTIVE,

View File

@ -349,6 +349,8 @@ VariationList<T>::VariationList()
ADDPREPOSTREGVAR(TileLog)
ADDPREPOSTREGVAR(TruchetFill)
ADDPREPOSTREGVAR(Waves2Radial)
ADDPREPOSTREGVAR(Panorama1)
ADDPREPOSTREGVAR(Panorama2)
//ADDPREPOSTREGVAR(LinearXZ)
//ADDPREPOSTREGVAR(LinearYZ)
//DC are special.

View File

@ -3768,22 +3768,24 @@ public:
virtual vector<string> OpenCLGlobalDataNames() const override
{
return vector<string> { "NOISE_INDEX", "NOISE_POINTS" };
return vector<string> { "NOISE_INDEX", "NOISE_POINTS", "OFFSETS" };
}
virtual string OpenCLFuncsString() const override
{
ostringstream os;
os <<
"static void Position(__constant real2* cache, __global real_t* p, __global real_t* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n"
"static void Position(__constant real_t* cache, __global real_t* p, __global real_t* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n"
"{\n"
" if (abs(x) <= " << CACHE_NUM << " && abs(y) <= " << CACHE_NUM << ")\n"
" {\n"
" *v = cache[((x + " << CACHE_NUM << ") * " << CACHE_WIDTH << ") + (y + " << CACHE_NUM << ")];\n"
" int index = (((x + " << CACHE_NUM << ") * " << CACHE_WIDTH << ") + (y + " << CACHE_NUM << ")) * 2;\n"
" (*v).x = cache[index];\n"
" (*v).y = cache[index + 1];\n"
" }\n"
" else\n"
" {\n"
" real3 e, f;\n"
" real4 e, f;\n"
" e.x = x * 2.5;\n"
" e.y = y * 2.5;\n"
" e.z = z * 2.5;\n"
@ -3818,6 +3820,7 @@ public:
<< "\t\treal2 u, dO;\n"
<< "\t\tint2 cv;\n"
<< "\t\treal2 p[" << VORONOI_MAXPOINTS << "];\n"
<< "\t\t__global real2* offset = (__global real2*)(globalShared + OFFSETS);\n"
<< "\n"
<< "\t\tif (" << cellSize << " == 0)\n"
<< "\t\t return;\n"
@ -3833,31 +3836,29 @@ public:
<< "\t\t{\n"
<< "\t\t for (dj = -1; dj < 2; dj++)\n"
<< "\t\t {\n"
<< "\t\t Position((__constant real2*)(&" << cache << "), globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]); \n"
<< "\t\t Position(&" << cache << ", globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]); \n"
<< "\t\t i++;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tint q = Closest(p, 9, &u);\n"
<< "\t\tint2 offset[9] = { { -1, -1 }, { -1, 0 }, { -1, 1 }, \n"
<< "\t\t{ 0, -1 }, { 0, 0 }, { 0, 1 },\n"
<< "\t\t{ 1, -1 }, { 1, 0 }, { 1, 1 } };\n"
<< "\t\tcv += offset[q];\n"
<< "\t\tcv.x += (int)offset[q].x;\n"
<< "\t\tcv.y += (int)offset[q].y;\n"
<< "\t\ti = 0;\n"
<< "\n"
<< "\t\tfor (di = -1; di < 2; di++)\n"
<< "\t\t{\n"
<< "\t\t for (dj = -1; dj < 2; dj++)\n"
<< "\t\t {\n"
<< "\t\t Position((__constant real2*)(&" << cache << "), globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t Position(&" << cache << ", globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n"
<< "\t\t i++;\n"
<< "\t\t }\n"
<< "\t\t}\n"
<< "\n"
<< "\t\tl = Voronoi(p, 9, 4, &u);\n"
<< "\t\tl = Zeps(Voronoi(p, 9, 4, &u));\n"
<< "\t\tdO = u - p[4];\n"
<< "\t\ttrgL = pow(fabs(Zeps(l)), " << power << ") * " << scale << ";\n"
<< "\t\tr = trgL / Zeps(l);\n"
<< "\t\ttrgL = pow(fabs(l), " << power << ") * " << scale << ";\n"
<< "\t\tr = trgL / l;\n"
<< "\t\tdO *= r;\n"
<< "\t\tdO += p[4];\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * dO.x;\n"

View File

@ -1461,6 +1461,92 @@ private:
T m_Distance;
};
/// <summary>
/// panorama1.
/// </summary>
template <typename T>
class Panorama1Variation : public Variation<T>
{
public:
Panorama1Variation(T weight = 1.0) : Variation<T>("panorama1", eVariationId::VAR_PANORAMA1, weight, true, false, false, false, false)
{
}
VARCOPY(Panorama1Variation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T aux = 1 / std::sqrt(helper.m_PrecalcSumSquares + 1);
T x1 = helper.m_TransX * aux;
T y1 = helper.m_TransY * aux;
aux = std::sqrt(x1 * x1 + y1 * y1);
helper.Out.x = m_Weight * std::atan2(x1, y1) * T(M_1_PI);
helper.Out.y = m_Weight * (aux - T(0.5));
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
ss << "\t{\n"
<< "\t\treal_t aux = 1.0 / sqrt(precalcSumSquares + 1);\n"
<< "\t\treal_t x1 = transX * aux;\n"
<< "\t\treal_t y1 = transY * aux;\n"
<< "\t\taux = sqrt(x1 * x1 + y1 * y1);\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * atan2(x1, y1) * M1PI;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (aux - 0.5);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
};
/// <summary>
/// panorama2.
/// </summary>
template <typename T>
class Panorama2Variation : public Variation<T>
{
public:
Panorama2Variation(T weight = 1.0) : Variation<T>("panorama2", eVariationId::VAR_PANORAMA2, weight, true, true, false, false, false)
{
}
VARCOPY(Panorama2Variation)
virtual void Func(IteratorHelper<T>& helper, Point<T>& outPoint, QTIsaac<ISAAC_SIZE, ISAAC_INT>& rand) override
{
T aux = 1 / (helper.m_PrecalcSqrtSumSquares + 1);
T x1 = helper.m_TransX * aux;
T y1 = helper.m_TransY * aux;
aux = std::sqrt(x1 * x1 + y1 * y1);
helper.Out.x = m_Weight * std::atan2(x1, y1) * T(M_1_PI);
helper.Out.y = m_Weight * (aux - T(0.5));
helper.Out.z = DefaultZ(helper);
}
virtual string OpenCLString() const override
{
ostringstream ss, ss2;
intmax_t varIndex = IndexInXform();
ss2 << "_" << XformIndexInEmber() << "]";
string index = ss2.str();
ss << "\t{\n"
<< "\t\treal_t aux = 1.0 / (precalcSqrtSumSquares + 1);\n"
<< "\t\treal_t x1 = transX * aux;\n"
<< "\t\treal_t y1 = transY * aux;\n"
<< "\t\taux = sqrt(x1 * x1 + y1 * y1);\n"
<< "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * atan2(x1, y1) * M1PI;\n"
<< "\t\tvOut.y = xform->m_VariationWeights[" << varIndex << "] * (aux - 0.5);\n"
<< "\t\tvOut.z = " << DefaultZCl()
<< "\t}\n";
return ss.str();
}
};
MAKEPREPOSTPARVAR(Splits3D, splits3D, SPLITS3D)
MAKEPREPOSTPARVAR(Waves2B, waves2b, WAVES2B)
MAKEPREPOSTPARVAR(JacCn, jac_cn, JAC_CN)
@ -1475,4 +1561,6 @@ MAKEPREPOSTVAR(Cylinder2, cylinder2, CYLINDER2)
MAKEPREPOSTPARVAR(TileLog, tile_log, TILE_LOG)
MAKEPREPOSTPARVAR(TruchetFill, Truchet_fill, TRUCHET_FILL)
MAKEPREPOSTPARVAR(Waves2Radial, waves2_radial, WAVES2_RADIAL)
MAKEPREPOSTVAR(Panorama1, panorama1, PANORAMA1)
MAKEPREPOSTVAR(Panorama2, panorama2, PANORAMA2)
}

View File

@ -1279,7 +1279,7 @@ public:
string notchBottom = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
string notchTop = "parVars[" + ToUpper(m_Params[i++].Name()) + index;
ss << "\t{\n"
<< "\t\treal3 v;\n"
<< "\t\treal4 v;\n"
<< "\t\treal_t vx, vy, col, r, theta, s, c, p, e;\n"
<< "\t\tint t = 0, iShape = (int)" << shape << ", iMap = (int)" << map << ", iOctaves = (int)" << octaves << ", iBailout = (int)" << selectBailout << ";\n"
<< "\n"

View File

@ -176,17 +176,16 @@ FunctionMapper::FunctionMapper()
" return ratiomax;\n"
"}\n";
s_GlobalMap["SimplexNoise3D"] =
"inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real_t* grad)\n"
"inline real_t SimplexNoise3D(real4* v, __global real_t* p, __global real_t* grad)\n"
"{\n"
" real3 c[4];\n"
" real4 c[4];\n"
" real_t n = 0;\n"
" int gi[4];\n"
" real_t t;\n"
" real_t skewIn = ((*v).x + (*v).y + (*v).z) * 0.333333;\n"
" int i = (int)floor((*v).x + skewIn);\n"
" int j = (int)floor((*v).y + skewIn);\n"
" int k = (int)floor((*v).z + skewIn);\n"
" t = (i + j + k) * 0.1666666;\n"
" real_t t = (i + j + k) * 0.1666666;\n"
" real_t x0 = i - t;\n"
" real_t y0 = j - t;\n"
" real_t z0 = k - t;\n"
@ -195,7 +194,7 @@ FunctionMapper::FunctionMapper()
" c[0].z = (*v).z - z0;\n"
" int i1, j1, k1;\n"
" int i2, j2, k2;\n"
" real3 u;\n"
" real4 u;\n"
"\n"
" if (c[0].x >= c[0].y)\n"
" {\n"
@ -257,9 +256,10 @@ FunctionMapper::FunctionMapper()
"\n"
" if (t > 0)\n"
" {\n"
" u.x = grad[(gi[corner] * 3)];\n"
" u.y = grad[(gi[corner] * 3) + 1];\n"
" u.z = grad[(gi[corner] * 3) + 2];\n"
" int index = gi[corner] * 3;\n"
" u.x = grad[index];\n"
" u.y = grad[index + 1];\n"
" u.z = grad[index + 2];\n"
" t *= t;\n"
" n += t * t * (u.x * c[corner].x + u.y * c[corner].y + u.z * c[corner].z);\n"
" }\n"
@ -268,11 +268,11 @@ FunctionMapper::FunctionMapper()
" return 32.0 * n;\n"
"}\n";
s_GlobalMap["PerlinNoise3D"] =
"inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real_t* grad, real_t aScale, real_t fScale, int octaves)\n"
"inline real_t PerlinNoise3D(real4* v, __global real_t* p, __global real_t* grad, real_t aScale, real_t fScale, int octaves)\n"
"{\n"
" int i;\n"
" real_t n = 0.0, a = 1.0;\n"
" real3 u = *v;\n"
" real4 u = *v;\n"
"\n"
" for (i = 0; i < octaves; i++)\n"
" {\n"

View File

@ -703,7 +703,7 @@ void IterOpenCLKernelCreator<T>::SharedDataIndexDefines(const Ember<T>& ember, p
if (auto dataInfo = varFuncs->GetSharedData(s))///Will contain a name, pointer to data, and size of the data in units of sizeof(T).
{
if (doString)
os << "#define " << ToUpper(name) << " " << offset << "\n";
os << "#define " << ToUpper(name) << " " << offset << '\n';
if (doVals)
params.second.insert(params.second.end(), dataInfo->first, dataInfo->first + dataInfo->second);
@ -719,7 +719,7 @@ void IterOpenCLKernelCreator<T>::SharedDataIndexDefines(const Ember<T>& ember, p
if (doString)
{
os << "\n";
os << "#define TOTAL_GLOBAL_SIZE_END " << offset << "\n\n";
params.first = os.str();
}
}