Compare commits

...
8 Commits
20 changed files with 271 additions and 8 deletions
+3
View File
@@ -48,6 +48,9 @@ enum RTCBufferType {
RTC_VERTEX_CREASE_WEIGHT_BUFFER = 0x08000000,
RTC_HOLE_BUFFER = 0x09000001,
RTC_PRIMITIVE_ORDER_BUFFER = 0x0A000000,
RTC_VERTEX_ORDER_BUFFER = 0x0B000000,
};
/*! \brief Supported types of matrix layout for functions involving matrices */
+17
View File
@@ -65,6 +65,23 @@ namespace embree
}
}
template<int N>
void BVHN<N>::sort(NodeRef& node)
{
if (node.isLeaf())
{
size_t num; char* prim = node.leaf(num);
for (size_t i=0; i<num; i++)
primTy.sort(prim+i*primTy.bytes,scene);
}
else
{
Node* n = node.node();
for (size_t c=0; c<N; c++)
sort(n->child(c));
}
}
template<int N>
void BVHN<N>::layoutLargeNodes(size_t num)
{
+3
View File
@@ -996,6 +996,9 @@ namespace embree
/*! Clears the barrier bits of a subtree. */
void clearBarrier(NodeRef& node);
/*! sort the leaves */
void sort(NodeRef& node);
/*! lays out num large nodes of the BVH */
void layoutLargeNodes(size_t num);
NodeRef layoutLargeNodesRecursion(NodeRef& node, FastAllocator::ThreadLocal& allocator);
+16
View File
@@ -201,6 +201,22 @@ namespace embree
});
#endif
#if 1
for (const auto& prim : prims) {
const unsigned geomID = prim.geomID();
const unsigned primID = prim.primID();
scene->get(geomID)->updatePrimitiveOrder(primID);
}
for (const auto& prim : prims) {
const unsigned geomID = prim.geomID();
const unsigned primID = prim.primID();
scene->get(geomID)->updateVertexOrder(primID);
}
bvh->sort(bvh->root);
#endif
/* clear temporary data for static geometry */
bool staticGeom = mesh ? mesh->isStatic() : scene->isStatic();
if (staticGeom) {
+8 -1
View File
@@ -75,6 +75,13 @@ namespace embree
BufferRefT (size_t num = 0, size_t stride = 0)
: BufferRef(num,stride) {}
/*! access to the ith element of the buffer stream */
__forceinline T& operator[](size_t i)
{
assert(i<num);
return *(T*)(ptr_ofs + i*stride);
}
/*! access to the ith element of the buffer stream */
__forceinline const T& operator[](size_t i) const
{
@@ -151,7 +158,7 @@ namespace embree
public:
/* inits the buffer */
void init(MemoryMonitorInterface* device_in, size_t num_in, size_t stride_in)
void init(MemoryMonitorInterface* device_in, size_t num_in, size_t stride_in = sizeof(T))
{
device = device_in;
ptr = nullptr;
+6
View File
@@ -45,6 +45,12 @@ namespace embree
/*! updates intersection filter function counts in scene */
void updateIntersectionFilters(bool enable);
/*! inserts a primitve into the primitive order */
virtual void updatePrimitiveOrder(unsigned primID) {}
/*! inserts a primitve into the vertex order */
virtual void updateVertexOrder(unsigned primID) {}
public:
/*! tests if geometry is enabled */
+26 -2
View File
@@ -19,12 +19,13 @@
namespace embree
{
TriangleMesh::TriangleMesh (Scene* parent, RTCGeometryFlags flags, size_t numTriangles, size_t numVertices, size_t numTimeSteps)
: Geometry(parent,TRIANGLE_MESH,numTriangles,numTimeSteps,flags)
: Geometry(parent,TRIANGLE_MESH,numTriangles,numTimeSteps,flags), primitive_order_counter(0), vertex_order_counter(0)
{
triangles.init(parent->device,numTriangles,sizeof(Triangle));
primitive_order.init(parent->device,numTriangles);
vertices.resize(numTimeSteps);
vertex_order.init(parent->device,numVertices);
for (size_t i=0; i<numTimeSteps; i++) {
vertices[i].init(parent->device,numVertices,sizeof(Vec3fa));
}
@@ -84,6 +85,12 @@ namespace embree
userbuffers[1]->set(ptr,offset,stride);
userbuffers[1]->checkPadding16();
break;
case RTC_PRIMITIVE_ORDER_BUFFER:
primitive_order.set(ptr,offset,stride);
break;
case RTC_VERTEX_ORDER_BUFFER:
vertex_order.set(ptr,offset,stride);
break;
default:
throw_RTCError(RTC_INVALID_ARGUMENT,"unknown buffer type");
@@ -204,4 +211,21 @@ namespace embree
}
}
}
void TriangleMesh::updatePrimitiveOrder(unsigned primID)
{
if (!primitive_order) return;
if (primitive_order[primID] != -1) return;
primitive_order[primID] = primitive_order_counter++;
}
void TriangleMesh::updateVertexOrder(unsigned primID)
{
if (!primitive_order) return;
if (!vertex_order) return;
Triangle& tri = triangles[primID];
if (vertex_order[tri.v[0]] == -1) vertex_order[tri.v[0]] = vertex_order_counter++;
if (vertex_order[tri.v[1]] == -1) vertex_order[tri.v[1]] = vertex_order_counter++;
if (vertex_order[tri.v[2]] == -1) vertex_order[tri.v[2]] = vertex_order_counter++;
}
}
+8
View File
@@ -113,6 +113,8 @@ namespace embree
bool verify ();
void interpolate(unsigned primID, float u, float v, RTCBufferType buffer, float* P, float* dPdu, float* dPdv, float* ddPdudu, float* ddPdvdv, float* ddPdudv, size_t numFloats);
// FIXME: implement interpolateN
virtual void updatePrimitiveOrder(unsigned primID);
virtual void updateVertexOrder(unsigned primID);
public:
@@ -257,5 +259,11 @@ namespace embree
BufferRefT<Vec3fa> vertices0; //!< fast access to first vertex buffer
vector<APIBuffer<Vec3fa>> vertices; //!< vertex array for each timestep
array_t<std::unique_ptr<APIBuffer<char>>,2> userbuffers; //!< user buffers // FIXME: no std::unique_ptr here
public:
unsigned primitive_order_counter;
unsigned vertex_order_counter;
APIBuffer<unsigned> primitive_order;
APIBuffer<unsigned> vertex_order;
};
}
+5
View File
@@ -97,6 +97,11 @@ namespace embree
return ((Triangle4i*)This)->size();
}
template<>
void Triangle4i::Type::sort(char* This, const Scene* scene) const {
((Triangle4i*)This)->sort(scene);
}
/********************** Triangle4vMB **************************/
template<>
+3
View File
@@ -32,6 +32,9 @@ namespace embree
/*! Returns the number of stored primitives in a block. */
virtual size_t size(const char* This) const = 0;
/*! fixes indices to the sorted version */
virtual void sort(char* This, const Scene* scene) const {}
public:
std::string name; //!< name of this primitive type
size_t bytes; //!< number of bytes of the triangle data
+24 -1
View File
@@ -31,6 +31,7 @@ namespace embree
{
Type();
size_t size(const char* This) const;
void sort(char* This, const Scene* scene) const;
};
static Type type;
@@ -63,7 +64,29 @@ namespace embree
/* Returns the number of stored triangles */
__forceinline size_t size() const { return __bsf(~movemask(valid())); }
__forceinline void sort(const Scene* scene)
{
for (size_t i=0; i<size(); i++)
{
const TriangleMesh* mesh = scene->getTriangleMesh(geomID(i));
if (mesh->vertex_order)
{
const TriangleMesh::Triangle& tri = mesh->triangles[primIDs[i]];
const unsigned i0 = mesh->vertex_order[tri.v[0]];
const unsigned i1 = mesh->vertex_order[tri.v[1]];
const unsigned i2 = mesh->vertex_order[tri.v[2]];
v0[i] = (Vec3f*) mesh->vertexPtr(i0);
v1[i] = int(size_t((int*)mesh->vertexPtr(i1)-(int*)v0[i]));
v2[i] = int(size_t((int*)mesh->vertexPtr(i2)-(int*)v0[i]));
primIDs[i] = mesh->primitive_order[primIDs[i]];
}
if (mesh->primitive_order)
primIDs[i] = mesh->primitive_order[primIDs[i]];
}
}
/* Returns the geometry IDs */
__forceinline vint<M> geomID() const { return geomIDs; }
__forceinline int geomID(const size_t i) const { assert(i<M); return geomIDs[i]; }
+103 -1
View File
@@ -31,6 +31,15 @@ namespace embree
SHADER_AMBIENT_OCCLUSION = 6
};
template<typename Vector>
void sort_vector(Vector& in, std::vector<unsigned> order)
{
if (in.size() == 0) return;
Vector tmp = in;
for (size_t i=0; i<in.size(); i++)
in[order[i]] = tmp[i];
}
/*! Scene representing the OBJ file */
struct TutorialScene
{
@@ -84,6 +93,12 @@ namespace embree
Type type;
Geometry (Type type) : type(type) {}
virtual void create_order_buffers() {}
virtual void sort() {}
virtual void randomize() {}
virtual std::pair<size_t,size_t> distance() {
return std::make_pair(size_t(0),size_t(0));
}
};
/*! Triangle Mesh. */
@@ -117,12 +132,69 @@ namespace embree
}
}
void create_order_buffers()
{
vertex_order.resize(positions.size(),-1);
primitive_order.resize(triangles.size(),-1);
}
void randomize()
{
create_order_buffers();
for (size_t i=0; i<primitive_order.size(); i++)
primitive_order[i] = i;
for (size_t i=0; i<primitive_order.size(); i++)
std::swap(primitive_order[i],primitive_order[rand()%primitive_order.size()]);
for (size_t i=0; i<vertex_order.size(); i++)
vertex_order[i] = i;
for (size_t i=0; i<vertex_order.size(); i++)
std::swap(vertex_order[i],vertex_order[rand()%vertex_order.size()]);
sort();
}
void sort()
{
if (primitive_order.size()) {
sort_vector(triangles,primitive_order);
}
if (vertex_order.size())
{
sort_vector(positions,vertex_order);
sort_vector(normals,vertex_order);
sort_vector(texcoords,vertex_order);
for (size_t i=0; i<triangles.size(); i++) {
Triangle& tri = triangles[i];
tri = Triangle(vertex_order[tri.v0],vertex_order[tri.v1],vertex_order[tri.v2],tri.materialID);
}
}
primitive_order.clear(); primitive_order.shrink_to_fit();
vertex_order.clear(); vertex_order.shrink_to_fit();
}
std::pair<size_t,size_t> distance()
{
size_t vertex_distance = 0;
size_t vertex_distance_den = 0;
for (size_t i=0; i<triangles.size(); i++)
{
Triangle& tri = triangles[i];
vertex_distance += std::abs(int(tri.v0-tri.v1));
vertex_distance += std::abs(int(tri.v1-tri.v2));
vertex_distance += std::abs(int(tri.v2-tri.v0));
vertex_distance_den += 3;
}
return std::make_pair(vertex_distance,vertex_distance_den);
}
public:
avector<Vec3fa> positions; //!< vertex positions for all time steps
avector<Vec3fa> normals; //!< vertex normals
std::vector<Vec2f> texcoords; //!< texture coordinates
std::vector<Triangle> triangles; //!< triangle indices
std::vector<unsigned> primitive_order;
std::vector<unsigned> vertex_order;
unsigned numTimeSteps;
unsigned numVertices;
unsigned materialID;
@@ -308,6 +380,36 @@ namespace embree
return geometries.size() == 0;
}
void create_order_buffers()
{
for (Ref<Geometry> geometry : geometries)
geometry->create_order_buffers();
}
void sort()
{
for (Ref<Geometry> geometry : geometries)
geometry->sort();
}
void randomize()
{
for (Ref<Geometry> geometry : geometries)
geometry->randomize();
}
double distance()
{
size_t vertex_distance = 0;
size_t vertex_distance_den = 0;
for (Ref<Geometry> geometry : geometries) {
auto p = geometry->distance();
vertex_distance += p.first;
vertex_distance_den += p.second;
}
return double(vertex_distance)/double(vertex_distance_den);
}
public:
avector<Material> materials; //!< material list
std::vector<Ref<Geometry> > geometries; //!< list of geometries
+4
View File
@@ -84,6 +84,8 @@ namespace embree
numTimeSteps = in->numTimeSteps;
numVertices = in->numVertices;
numTriangles = unsigned(in->triangles.size());
primitive_order = in->primitive_order.data();
vertex_order = in->vertex_order.data();
geomID = -1;
materialID = in->materialID;
}
@@ -94,6 +96,8 @@ namespace embree
Vec3fa* normals; //!< vertex normal array
Vec2f* texcoords; //!< vertex texcoord array
ISPCTriangle* triangles; //!< list of triangles
unsigned* primitive_order;
unsigned* vertex_order;
unsigned int numTimeSteps;
unsigned int numVertices;
@@ -48,6 +48,8 @@ struct ISPCTriangleMesh
uniform Vec3fa* normals; //!< vertex normal array
uniform Vec2f* texcoords; //!< vertex texcoord array
uniform ISPCTriangle* triangles; //!< list of triangles
uniform unsigned int* primitive_order;
uniform unsigned int* vertex_order;
unsigned int numTimeSteps;
unsigned int numVertices;
unsigned int numTriangles;
+32 -2
View File
@@ -46,6 +46,7 @@ namespace embree
float g_debug = 0.0f;
Mode g_mode = MODE_NORMAL;
ISPCScene* g_ispc_scene = nullptr;
TutorialScene* g_tutorial_scene = nullptr;
/* intensity scaling for traversal cost visualization */
float scale = 1.0f / 1000000.0f;
@@ -214,7 +215,9 @@ namespace embree
convert_hair_to_curves(false),
sceneFilename(""),
instancing_mode(0),
subdiv_mode("")
subdiv_mode(""),
sort_geometry(false),
randomize_geometry(false)
{
registerOption("i", [this] (Ref<ParseStream> cin, const FileName& path) {
sceneFilename = path + cin->getFileName();
@@ -358,6 +361,16 @@ namespace embree
subdiv_mode = ",subdiv_accel=bvh4.grid.eager";
rtcore += subdiv_mode;
}, "--pregenerate: enabled pregenerate subdiv mode");
registerOption("sort-geometry", [this] (Ref<ParseStream> cin, const FileName& path) {
sort_geometry = true;
randomize_geometry = false;
}, "--sort-geometry: sorts primitives and vertices for more coherent memory access");
registerOption("randomize-geometry", [this] (Ref<ParseStream> cin, const FileName& path) {
sort_geometry = false;
randomize_geometry = true;
}, "--randomize-geometry: randomizes primitives and vertices");
}
void TutorialApplication::renderBenchmark()
@@ -451,9 +464,18 @@ namespace embree
pixels = (unsigned*) alignedMalloc(width*height*sizeof(unsigned),64);
}
void TutorialApplication::set_scene (TutorialScene* in) {
void TutorialApplication::set_scene (TutorialScene* in)
{
g_tutorial_scene = in;
g_ispc_scene = new ISPCScene(in);
}
extern "C" void sort_scene()
{
g_tutorial_scene->sort();
double distance = g_tutorial_scene->distance();
std::cout << "average vertex distance = " << distance / 4.0f << " vertices " << std::endl;
}
void TutorialApplication::keyboardFunc(unsigned char key, int x, int y)
{
@@ -757,6 +779,14 @@ namespace embree
obj_scene.add(scene.dynamicCast<SceneGraph::Node>(),(TutorialScene::InstancingMode)instancing_mode);
scene = nullptr;
/* randomize geometry */
if (randomize_geometry)
obj_scene.randomize();
/* create order buffers if we need to sort the geometry */
if (sort_geometry)
obj_scene.create_order_buffers();
/* send model */
set_scene(&obj_scene);
+2
View File
@@ -130,5 +130,7 @@ namespace embree
FileName sceneFilename;
int instancing_mode;
std::string subdiv_mode;
bool sort_geometry;
bool randomize_geometry;
};
}
@@ -53,6 +53,8 @@ enum Mode {
extern "C" Mode g_mode;
extern "C" void sort_scene();
/* error reporting function */
void error_handler(const RTCError code, const char* str = nullptr);
@@ -903,6 +903,8 @@ unsigned int convertTriangleMesh(ISPCTriangleMesh* mesh, RTCScene scene_out)
rtcSetBuffer(scene_out, geomID, (RTCBufferType)(RTC_VERTEX_BUFFER+t), mesh->positions+t*mesh->numVertices, 0, sizeof(Vec3fa ));
}
rtcSetBuffer(scene_out, geomID, RTC_INDEX_BUFFER, mesh->triangles, 0, sizeof(ISPCTriangle));
rtcSetBuffer(scene_out, geomID, RTC_PRIMITIVE_ORDER_BUFFER, mesh->primitive_order, 0, sizeof(unsigned));
rtcSetBuffer(scene_out, geomID, RTC_VERTEX_ORDER_BUFFER, mesh->vertex_order, 0, sizeof(unsigned));
mesh->geomID = geomID;
#if ENABLE_FILTER_FUNCTION == 1
rtcSetOcclusionFilterFunction(scene_out,geomID,(RTCFilterFunc)&occlusionFilterOpaque);
@@ -1224,6 +1226,8 @@ RTCScene convertScene(ISPCScene* scene_in)
rtcSetProgressMonitorFunction(scene_out,nullptr,nullptr);
progressEnd();
sort_scene();
return scene_out;
} // convertScene
-1
View File
@@ -36,7 +36,6 @@ namespace embree
g_instancing_mode = instancing_mode;
}
};
}
int main(int argc, char** argv) {
+3
View File
@@ -132,6 +132,8 @@ unsigned int convertTriangleMesh(ISPCTriangleMesh* mesh, RTCScene scene_out)
rtcSetBuffer(scene_out, geomID, (RTCBufferType)(RTC_VERTEX_BUFFER+t), mesh->positions+t*mesh->numVertices, 0, sizeof(Vec3fa ));
}
rtcSetBuffer(scene_out, geomID, RTC_INDEX_BUFFER, mesh->triangles, 0, sizeof(ISPCTriangle));
rtcSetBuffer(scene_out, geomID, RTC_PRIMITIVE_ORDER_BUFFER, mesh->primitive_order, 0, sizeof(unsigned));
rtcSetBuffer(scene_out, geomID, RTC_VERTEX_ORDER_BUFFER, mesh->vertex_order, 0, sizeof(unsigned));
mesh->geomID = geomID;
return geomID;
}
@@ -635,6 +637,7 @@ extern "C" void device_render (int* pixels,
g_scene = convertScene(g_ispc_scene);
if (g_subdiv_mode) updateEdgeLevels(g_ispc_scene, camera.xfm.p);
rtcCommit (g_scene);
sort_scene();
old_p = camera.xfm.p;
}