Commit 9af471af authored by Johannes Braun's avatar Johannes Braun
Browse files

Made Line Space offsets non-precalculated to not have a mess in the shader....

Made Line Space offsets non-precalculated to not have a mess in the shader. (Might even seem to be faster)
parent 3806db9e
...@@ -132,12 +132,11 @@ struct Line ...@@ -132,12 +132,11 @@ struct Line
struct Linespace struct Linespace
{ {
Line* lines; Line* lines;
uint p[2]; uint arb_prop; // Some arbitrary property free to use (or not to use)
uint line_count;
Bounds bounds; Bounds bounds;
uvec3 resolution; uvec3 resolution;
float patch_size; float patch_size;
uint offsets[15];
uint line_count;
}; };
struct Mesh struct Mesh
......
...@@ -77,7 +77,7 @@ uint id_from_direction(vec3 direction, uint quarter_subdivision, uint face, uint ...@@ -77,7 +77,7 @@ uint id_from_direction(vec3 direction, uint quarter_subdivision, uint face, uint
uint lineIndex(const in Ray ray, const in Mesh mesh, float t, int face, bool reverse) uint lineIndex(const in Ray ray, const in Mesh mesh, float t, int face, bool reverse)
{ {
const Linespace linespace = mesh.linespace; const Linespace linespace = mesh.linespace;
const uint radial_subdivisions = linespace.offsets[0]; const uint radial_subdivisions = linespace.arb_prop;
uint dir_id = id_from_direction(normalize(ray.direction), radial_subdivisions, face, face % 3, face_width_axis[face % 3], face_height_axis[face % 3]); uint dir_id = id_from_direction(normalize(ray.direction), radial_subdivisions, face, face % 3, face_width_axis[face % 3], face_height_axis[face % 3]);
......
...@@ -12,23 +12,64 @@ uint ls__faceRangeIndex(uint in_face, uint out_face) ...@@ -12,23 +12,64 @@ uint ls__faceRangeIndex(uint in_face, uint out_face)
return uint((((-0.5f * float(in_face)) + 4.5f)*float(in_face))) - 1u + out_face; return uint((((-0.5f * float(in_face)) + 4.5f)*float(in_face))) - 1u + out_face;
} }
// Equal to... const uint c_face_width_axis[3] = {2, 2, 0};
// uint offset = linespace.offsets[index]; const uint c_face_height_axis[3] = {1, 0, 1};
// But working.
// Due to the index which has to be constant, this for loop is better. uint linesBetweenFaces(const in Linespace linespace, uint inface, uint outface)
//
//TODO: Wait for a fix. Or fix it somehow. Driver bug?
uint offsetof(const in Linespace linespace, const in uint index)
{ {
for(uint id = 0; id<15; ++id) uint axis_in_width = linespace.resolution[c_face_width_axis[inface % 3]];
uint axis_in_height = linespace.resolution[c_face_height_axis[inface % 3]];
uint axis_out_width = linespace.resolution[c_face_width_axis[outface % 3]];
uint axis_out_height = linespace.resolution[c_face_height_axis[outface % 3]];
return axis_in_width * axis_in_height * axis_out_width * axis_out_height;
}
uint offsetOf(const in Linespace linespace, uint inface, uint outface)
{
uint offset = 0;
// Caution! Fallthrough switch. Seemed to perform much better than a for-loop, usually even being faster than precalculated offsets in release builds.
switch (ls__faceRangeIndex(inface, outface))
{ {
if(id==index) return linespace.offsets[id]; case 15:
offset += linesBetweenFaces(linespace, 4, 5);
case 14:
offset += linesBetweenFaces(linespace, 3, 5);
case 13:
offset += linesBetweenFaces(linespace, 3, 4);
case 12:
offset += linesBetweenFaces(linespace, 2, 5);
case 11:
offset += linesBetweenFaces(linespace, 2, 4);
case 10:
offset += linesBetweenFaces(linespace, 2, 3);
case 9:
offset += linesBetweenFaces(linespace, 1, 5);
case 8:
offset += linesBetweenFaces(linespace, 1, 4);
case 7:
offset += linesBetweenFaces(linespace, 1, 3);
case 6:
offset += linesBetweenFaces(linespace, 1, 2);
case 5:
offset += linesBetweenFaces(linespace, 0, 5);
case 4:
offset += linesBetweenFaces(linespace, 0, 4);
case 3:
offset += linesBetweenFaces(linespace, 0, 3);
case 2:
offset += linesBetweenFaces(linespace, 0, 2);
case 1:
offset += linesBetweenFaces(linespace, 0, 1);
case 0:
default:
break;
} }
return 0;
}
const uint c_face_width_axis[3] = {2, 2, 0}; return offset;
const uint c_face_height_axis[3] = {1, 0, 1}; }
uint getFaceWidth(uint axis){ uint getFaceWidth(uint axis){
return c_face_width_axis[axis]; return c_face_width_axis[axis];
...@@ -102,7 +143,7 @@ uint ls__lineIndex(const in Ray ray, const in Mesh mesh, float tmin, float tmax, ...@@ -102,7 +143,7 @@ uint ls__lineIndex(const in Ray ray, const in Mesh mesh, float tmin, float tmax,
exit_info.patch_index = getPatch(mesh, exit_info.position, exit_info.axis, exit_info.face); exit_info.patch_index = getPatch(mesh, exit_info.position, exit_info.axis, exit_info.face);
//Now with all that information, we can retrieve the line index. //Now with all that information, we can retrieve the line index.
uint offset = offsetof(linespace, ls__faceRangeIndex(entry_info.face, exit_info.face)); uint offset = offsetOf(linespace, entry_info.face, exit_info.face);
uint start_height = linespace.resolution[getFaceHeight(entry_info.axis)]; uint start_height = linespace.resolution[getFaceHeight(entry_info.axis)];
uint end_width = linespace.resolution[getFaceWidth(exit_info.axis)]; uint end_width = linespace.resolution[getFaceWidth(exit_info.axis)];
......
...@@ -15,7 +15,6 @@ uniform uint u_begin_face; ...@@ -15,7 +15,6 @@ uniform uint u_begin_face;
uniform uint u_end_face; uniform uint u_end_face;
uniform uint u_begin_count; uniform uint u_begin_count;
uniform uint u_end_count; uniform uint u_end_count;
uniform uint u_offsets[15];
// General inputs // General inputs
uniform uvec3 u_subdivisions = uvec3(1, 1, 1); uniform uvec3 u_subdivisions = uvec3(1, 1, 1);
...@@ -57,10 +56,65 @@ uint faceRangeIndex(uint in_face, uint out_face) ...@@ -57,10 +56,65 @@ uint faceRangeIndex(uint in_face, uint out_face)
return uint((((-0.5f * float(in_face)) + 4.5f) * float(in_face))) - 1u + out_face; return uint((((-0.5f * float(in_face)) + 4.5f) * float(in_face))) - 1u + out_face;
} }
uint linesBetweenFaces(uint inface, uint outface)
{
uint axis_in_width = u_subdivisions[face_width_axis[inface % 3]];
uint axis_in_height = u_subdivisions[face_height_axis[inface % 3]];
uint axis_out_width = u_subdivisions[face_width_axis[outface % 3]];
uint axis_out_height = u_subdivisions[face_height_axis[outface % 3]];
return axis_in_width * axis_in_height * axis_out_width * axis_out_height;
}
uint offsetOf(uint inface, uint outface)
{
uint offset = 0;
// Caution! Fallthrough switch. Seemed to perform much better than a for-loop, usually even being faster than precalculated offsets in release builds.
switch (faceRangeIndex(inface, outface))
{
case 15:
offset += linesBetweenFaces(4, 5);
case 14:
offset += linesBetweenFaces(3, 5);
case 13:
offset += linesBetweenFaces(3, 4);
case 12:
offset += linesBetweenFaces(2, 5);
case 11:
offset += linesBetweenFaces(2, 4);
case 10:
offset += linesBetweenFaces(2, 3);
case 9:
offset += linesBetweenFaces(1, 5);
case 8:
offset += linesBetweenFaces(1, 4);
case 7:
offset += linesBetweenFaces(1, 3);
case 6:
offset += linesBetweenFaces(1, 2);
case 5:
offset += linesBetweenFaces(0, 5);
case 4:
offset += linesBetweenFaces(0, 4);
case 3:
offset += linesBetweenFaces(0, 3);
case 2:
offset += linesBetweenFaces(0, 2);
case 1:
offset += linesBetweenFaces(0, 1);
case 0:
default:
break;
}
return offset;
}
uint lineIndex(const in Patch begin, const in Patch end) uint lineIndex(const in Patch begin, const in Patch end)
{ {
uint range_section = faceRangeIndex(begin.face, end.face); uint offset = offsetOf(begin.face, end.face);
uint offset = u_offsets[range_section];
uint start_height = uint(u_subdivisions[face_height_axis[begin.face%3]]); uint start_height = uint(u_subdivisions[face_height_axis[begin.face%3]]);
uint end_width = uint(u_subdivisions[face_width_axis[end.face%3]]); uint end_width = uint(u_subdivisions[face_width_axis[end.face%3]]);
......
#include <iostream> #include <iostream>
#include <array>
#include <core/numeric/geometry.h>
#include <glm/ext.hpp>
#include <core/time.h>
#include <util/log.h>
//using namespace glare;
enum class Face : uint32_t
{
ePosX = 0,
ePosY = 1,
ePosZ = 2,
eNegX = 3,
eNegY = 4,
eNegZ = 5
};
math::Subdivision m_subdivision{ glm::uvec3(6, 2, 4), 0.14f };
const glm::uvec3 face_width_axises = { 2, 2, 0 };
const glm::uvec3 face_height_axises = { 1, 0, 1 };
std::array<size_t, 15> m_offsets;
std::array<size_t, 15> m_offsets_indirect;
std::array<size_t, 15> m_offsets_direct;
size_t faceRangeIndex(Face in, Face out)
{
return size_t((((-0.5 * unsigned(in)) + 4.5)*unsigned(in)) - 1 + unsigned(out));
}
size_t linesBetweenFaces(Face in, Face out)
{
unsigned axis_in_width = m_subdivision.resolution[face_width_axises[unsigned(in) % 3]];
unsigned axis_in_height = m_subdivision.resolution[face_height_axises[unsigned(in) % 3]];
unsigned axis_out_width = m_subdivision.resolution[face_width_axises[unsigned(out) % 3]];
unsigned axis_out_height = m_subdivision.resolution[face_height_axises[unsigned(out) % 3]];
return axis_in_width * axis_in_height * axis_out_width * axis_out_height;
}
const std::array<std::pair<Face, Face>, 15> start_end_patches
{
// pos x to...
std::pair<Face, Face>{Face::ePosX, Face::ePosY},
std::pair<Face, Face>{Face::ePosX, Face::ePosZ},
std::pair<Face, Face>{Face::ePosX, Face::eNegX},
std::pair<Face, Face>{Face::ePosX, Face::eNegY},
std::pair<Face, Face>{Face::ePosX, Face::eNegZ},
//pos y to...
std::pair<Face, Face>{Face::ePosY, Face::ePosZ},
std::pair<Face, Face>{Face::ePosY, Face::eNegX},
std::pair<Face, Face>{Face::ePosY, Face::eNegY},
std::pair<Face, Face>{Face::ePosY, Face::eNegZ},
//pos z to...
std::pair<Face, Face>{Face::ePosZ, Face::eNegX},
std::pair<Face, Face>{Face::ePosZ, Face::eNegY},
std::pair<Face, Face>{Face::ePosZ, Face::eNegZ},
//neg x to...
std::pair<Face, Face>{Face::eNegX, Face::eNegY},
std::pair<Face, Face>{Face::eNegX, Face::eNegZ},
//neg y to...
std::pair<Face, Face>{Face::eNegY, Face::eNegZ},
//no further configurations needed.
};
void calculateOffsets()
{
size_t current_offset = 0;
for (Face start = Face::ePosX; start < Face::eNegZ; start = Face(unsigned(start) + 1))
for (Face end = Face(unsigned(start) + 1); end <= Face::eNegZ; end = Face(unsigned(end) + 1))
{
size_t index = faceRangeIndex(start, end);
m_offsets[index] = current_offset;
current_offset += linesBetweenFaces(start, end);
}
}
template<int i=0>
size_t offsetOf(Face in, Face out)
{
// S0 = (end*sxsy) * (clamp(end, 1, 2) * lr + clamp(end, 2, 4)-2 * tb + clamp(end, 4, 5) * opp)
size_t offset = 0;
switch (faceRangeIndex(in, out))
{
case 15:
offset += linesBetweenFaces(Face::eNegY, Face::eNegZ);
case 14:
offset += linesBetweenFaces(Face::eNegX, Face::eNegZ);
case 13:
offset += linesBetweenFaces(Face::eNegX, Face::eNegY);
case 12:
offset += linesBetweenFaces(Face::ePosZ, Face::eNegZ);
case 11:
offset += linesBetweenFaces(Face::ePosZ, Face::eNegY);
case 10:
offset += linesBetweenFaces(Face::ePosZ, Face::eNegX);
case 9:
offset += linesBetweenFaces(Face::ePosY, Face::eNegZ);
case 8:
offset += linesBetweenFaces(Face::ePosY, Face::eNegY);
case 7:
offset += linesBetweenFaces(Face::ePosY, Face::eNegX);
case 6:
offset += linesBetweenFaces(Face::ePosY, Face::ePosZ);
case 5:
offset += linesBetweenFaces(Face::ePosX, Face::eNegZ);
case 4:
offset += linesBetweenFaces(Face::ePosX, Face::eNegY);
case 3:
offset += linesBetweenFaces(Face::ePosX, Face::eNegX);
case 2:
offset += linesBetweenFaces(Face::ePosX, Face::ePosZ);
case 1:
offset += linesBetweenFaces(Face::ePosX, Face::ePosY);
case 0:
default:
break;
}
return offset;
}
template<>
size_t offsetOf<1>(Face in, Face out)
{
size_t offset = 0;
size_t fri = faceRangeIndex(in, out);
for (int i = fri; i > 0; --i)
{
auto step = start_end_patches[i-1];
offset += linesBetweenFaces(step.first, step.second);
}
return offset;
}
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
for (int s = 0; s < 20; ++s)
{
glare::core::ClockMS clock;
long start = clock.restart();
calculateOffsets();
for (int i = 0; i < 10000000; ++i)
{
size_t y = 0;
for (Face start = Face::ePosX; start < Face::eNegZ; start = Face(unsigned(start) + 1))
for (Face end = Face(unsigned(start) + 1); end <= Face::eNegZ; end = Face(unsigned(end) + 1))
{
int fri = faceRangeIndex(start, end);
for (int i = 0; i < 15; ++i)
{
if (i == fri)
{
m_offsets_indirect[y++] = m_offsets[i];
}
}
}
}
long smp = clock.restart();
for (int a = 0; a < 10000000; ++a)
{
size_t i = 0;
for (const auto& se : start_end_patches)
{
m_offsets_direct[i++] = offsetOf<1>(se.first, se.second);
}
}
long ft = clock.restart();
if (smp < ft)
{
Log_Error << "Times: " << start << ", " << smp << ", " << ft;
}
else
{
Log_Info << "Times: " << start << ", " << smp << ", " << ft;
}
}
system("pause"); system("pause");
} }
\ No newline at end of file
...@@ -257,7 +257,7 @@ namespace glare ...@@ -257,7 +257,7 @@ namespace glare
data.resolution = glm::uvec3(m_subdivision.resolution); data.resolution = glm::uvec3(m_subdivision.resolution);
data.lines = m_line_buffer.residentAddress(); data.lines = m_line_buffer.residentAddress();
data.offsets[0] = unsigned(m_radial_subdivisions); data.arb_prop = unsigned(m_radial_subdivisions);
data.line_count = glm::uint(m_num_lines); data.line_count = glm::uint(m_num_lines);
return data; return data;
......
...@@ -61,9 +61,7 @@ namespace glare ...@@ -61,9 +61,7 @@ namespace glare
m_face_widths = { m_subdivision.resolution.z, m_subdivision.resolution.z, m_subdivision.resolution.x }; m_face_widths = { m_subdivision.resolution.z, m_subdivision.resolution.z, m_subdivision.resolution.x };
m_face_heights = { m_subdivision.resolution.y, m_subdivision.resolution.x, m_subdivision.resolution.y }; m_face_heights = { m_subdivision.resolution.y, m_subdivision.resolution.x, m_subdivision.resolution.y };
// initialize m_offsets
Log_Info << "Building Line Space for collector id " << collector.id() << "..."; Log_Info << "Building Line Space for collector id " << collector.id() << "...";
calculateOffsets();
core::ClockGL::instance().start(); core::ClockGL::instance().start();
...@@ -182,11 +180,8 @@ namespace glare ...@@ -182,11 +180,8 @@ namespace glare
m_construction_shader->uniform("u_bounds.min", m_bounds.min); m_construction_shader->uniform("u_bounds.min", m_bounds.min);
m_construction_shader->uniform("u_bounds.max", m_bounds.max); m_construction_shader->uniform("u_bounds.max", m_bounds.max);
m_construction_shader->storageBuffer("line_buffer", m_line_buffer); m_construction_shader->storageBuffer("line_buffer", m_line_buffer);
glFinish();
m_construction_shader->uniform("u_subdivisions", m_subdivision.resolution); m_construction_shader->uniform("u_subdivisions", m_subdivision.resolution);
m_construction_shader->uniform("u_subdivisions_size", m_subdivision.size); m_construction_shader->uniform("u_subdivisions_size", m_subdivision.size);
glFinish();
for (int i = 0; i < 15; ++i) { for (int i = 0; i < 15; ++i) {
m_construction_shader->uniform("u_offsets[" + std::to_string(i) + "]", unsigned(m_offsets[i])); m_construction_shader->uniform("u_offsets[" + std::to_string(i) + "]", unsigned(m_offsets[i]));
...@@ -218,18 +213,49 @@ namespace glare ...@@ -218,18 +213,49 @@ namespace glare
} }
} }
void Linespace::calculateOffsets() size_t Linespace::offsetOf(Face in, Face out)
{ {
size_t current_offset = 0; size_t offset = 0;
for (Face start = Face::ePosX; start < Face::eNegZ; start = Face(unsigned(start) + 1)) // Caution! Fallthrough switch. Seemed to perform much better than a for-loop, usually even being faster than precalculated offsets in release builds.
for (Face end = Face(unsigned(start) + 1); end <= Face::eNegZ; end = Face(unsigned(end) + 1)) switch (faceRangeIndex(in, out))
{ {
size_t index = faceRangeIndex(start, end); case 15:
m_offsets[index] = current_offset; offset += linesBetweenFaces(Face::eNegY, Face::eNegZ);
case 14:
offset += linesBetweenFaces(Face::eNegX, Face::eNegZ);
case 13:
offset += linesBetweenFaces(Face::eNegX, Face::eNegY);
case 12:
offset += linesBetweenFaces(Face::ePosZ, Face::eNegZ);
case 11:
offset += linesBetweenFaces(Face::ePosZ, Face::eNegY);
case 10:
offset += linesBetweenFaces(Face::ePosZ, Face::eNegX);
case 9:
offset += linesBetweenFaces(Face::ePosY, Face::eNegZ);
case 8:
offset += linesBetweenFaces(Face::ePosY, Face::eNegY);
case 7:
offset += linesBetweenFaces(Face::ePosY, Face::eNegX);
case 6:
offset += linesBetweenFaces(Face::ePosY, Face::ePosZ);
case 5:
offset += linesBetweenFaces(Face::ePosX, Face::eNegZ);
case 4:
offset += linesBetweenFaces(Face::ePosX, Face::eNegY);
case 3:
offset += linesBetweenFaces(Face::ePosX, Face::eNegX);
case 2:
offset += linesBetweenFaces(Face::ePosX, Face::ePosZ);
case 1:
offset += linesBetweenFaces(Face::ePosX, Face::ePosY);
case 0:
default:
break;
}
current_offset += linesBetweenFaces(start, end); return offset;
}
} }
glm::vec3 Linespace::patchCenter(const SurfacePatch &patch) glm::vec3 Linespace::patchCenter(const SurfacePatch &patch)
...@@ -269,8 +295,7 @@ namespace glare ...@@ -269,8 +295,7 @@ namespace glare
size_t Linespace::lineIndex(const SurfacePatch &in, const SurfacePatch &out) size_t Linespace::lineIndex(const SurfacePatch &in, const SurfacePatch &out)
{ {
size_t range_section = faceRangeIndex(in.face, out.face); size_t offset = offsetOf(in.face, out.face);
size_t offset = m_offsets[range_section];
size_t start_height = m_subdivision.resolution[face_height_axises[unsigned(in.face) % 3]]; size_t start_height = m_subdivision.resolution[face_height_axises[unsigned(in.face) % 3]];
size_t end_width = m_subdivision.resolution[face_width_axises[unsigned(out.face) % 3]]; size_t end_width = m_subdivision.resolution[face_width_axises[unsigned(out.face) % 3]];
...@@ -301,11 +326,6 @@ namespace glare ...@@ -301,11 +326,6 @@ namespace glare
data.patch_size = m_subdivision.size; data.patch_size = m_subdivision.size;
data.resolution = glm::uvec3(m_subdivision.resolution); data.resolution = glm::uvec3(m_subdivision.resolution);
data.lines = m_line_buffer.residentAddress(); data.lines = m_line_buffer.residentAddress();
for (int i = 0; i < 15; ++i) {
data.offsets[i] = glm::uint(m_offsets[i]);
}
data.line_count = glm::uint(calculateLineCount()); data.line_count = glm::uint(calculateLineCount());
return data; return data;
} }
......
...@@ -45,21 +45,13 @@ namespace glare ...@@ -45,21 +45,13 @@ namespace glare
}; };
}; };
struct bla
{
int i;
void operator=(int b)
{
i = b;
}
};
struct Line struct Line
{ {
using triangle_id_t = unsigned;
//hit triangle id's //hit triangle id's
bla nearest; triangle_id_t nearest;
bla farthest; triangle_i