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
struct Linespace
{
Line* lines;
uint p[2];
uint arb_prop; // Some arbitrary property free to use (or not to use)
uint line_count;
Bounds bounds;
uvec3 resolution;
float patch_size;
uint offsets[15];
uint line_count;
};
struct Mesh
......
......@@ -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)
{
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]);
......
......@@ -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;
}
// Equal to...
// uint offset = linespace.offsets[index];
// But working.
// Due to the index which has to be constant, this for loop is better.
//
//TODO: Wait for a fix. Or fix it somehow. Driver bug?
uint offsetof(const in Linespace linespace, const in uint index)
const uint c_face_width_axis[3] = {2, 2, 0};
const uint c_face_height_axis[3] = {1, 0, 1};
uint linesBetweenFaces(const in Linespace linespace, uint inface, uint outface)
{
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};
const uint c_face_height_axis[3] = {1, 0, 1};
return offset;
}
uint getFaceWidth(uint 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,
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.
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 end_width = linespace.resolution[getFaceWidth(exit_info.axis)];
......
......@@ -15,7 +15,6 @@ uniform uint u_begin_face;
uniform uint u_end_face;
uniform uint u_begin_count;
uniform uint u_end_count;
uniform uint u_offsets[15];
// General inputs
uniform uvec3 u_subdivisions = uvec3(1, 1, 1);
......@@ -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;
}
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 range_section = faceRangeIndex(begin.face, end.face);
uint offset = u_offsets[range_section];
uint offset = offsetOf(begin.face, end.face);
uint start_height = uint(u_subdivisions[face_height_axis[begin.face%3]]);
uint end_width = uint(u_subdivisions[face_width_axis[end.face%3]]);
......
#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[])
{
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");
}
\ No newline at end of file
......@@ -257,7 +257,7 @@ namespace glare
data.resolution = glm::uvec3(m_subdivision.resolution);
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);
return data;
......
......@@ -61,9 +61,7 @@ namespace glare
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 };
// initialize m_offsets
Log_Info << "Building Line Space for collector id " << collector.id() << "...";
calculateOffsets();
core::ClockGL::instance().start();
......@@ -182,11 +180,8 @@ namespace glare
m_construction_shader->uniform("u_bounds.min", m_bounds.min);
m_construction_shader->uniform("u_bounds.max", m_bounds.max);
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_size", m_subdivision.size);
glFinish();
for (int i = 0; i < 15; ++i) {
m_construction_shader->uniform("u_offsets[" + std::to_string(i) + "]", unsigned(m_offsets[i]));
......@@ -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))
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;
// Caution! Fallthrough switch. Seemed to perform much better than a for-loop, usually even being faster than precalculated offsets in release builds.
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;
}
current_offset += linesBetweenFaces(start, end);
}
return offset;
}
glm::vec3 Linespace::patchCenter(const SurfacePatch &patch)
......@@ -269,8 +295,7 @@ namespace glare
size_t Linespace::lineIndex(const SurfacePatch &in, const SurfacePatch &out)
{
size_t range_section = faceRangeIndex(in.face, out.face);
size_t offset = m_offsets[range_section];
size_t offset = offsetOf(in.face, out.face);
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]];
......@@ -301,11 +326,6 @@ namespace glare
data.patch_size = m_subdivision.size;
data.resolution = glm::uvec3(m_subdivision.resolution);
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());
return data;
}
......
......@@ -45,21 +45,13 @@ namespace glare
};
};
struct bla
{
int i;
void operator=(int b)
{
i = b;
}
};
struct Line
{
using triangle_id_t = unsigned;
//hit triangle id's
bla nearest;
bla farthest;
triangle_id_t nearest;
triangle_id_t farthest;
};
const glm::uvec3 face_width_axises = { 2, 2, 0 };
......@@ -126,7 +118,7 @@ namespace glare
void generateCPU(const LocalCollector &collector);
void generateGPU(const LocalCollector &collector);
void calculateOffsets();
size_t offsetOf(Face in, Face out);
size_t linesBetweenFaces(Face in, Face out);
size_t lineIndex(const SurfacePatch &in, const SurfacePatch &out);
......
......@@ -89,12 +89,11 @@ namespace glare
struct LinespaceData
{
uint64_t lines;
glm::uint p[2];
uint32_t arb_prop; // Some arbitrary property free to use (or not to use)
uint32_t line_count;
math::Bounds bounds;
glm::uvec3 resolution;
float patch_size;
glm::uint offsets[15];
glm::uint line_count;
};
struct Mesh
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment