// -------------------------------------------------------------------------------------------------------------------- bool UntexturedObjectsGLBindless::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices, const std::vector<UntexturedObjectsProblem::Index>& _indices, size_t _objectCount) { if (glBufferStorage == nullptr) { console::warn("Unable to initialize solution '%s', glBufferStorage() unavailable.", GetName().c_str()); return false; } if (glGetBufferParameterui64vNV == nullptr || glMakeBufferResidentNV == nullptr) { console::warn("Unable to initialize solution '%s', GL_NV_shader_buffer_load unavailable.", GetName().c_str()); return false; } if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) { return false; } // Program const char* kUniformNames[] = { "ViewProjection", "World", nullptr }; m_prog = CreateProgramT("cubes_gl_bindless_vs.glsl", "cubes_gl_bindless_fs.glsl", kUniformNames, &mUniformLocation); if (m_prog == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } m_ibs.resize(_objectCount); m_ib_addrs.resize(_objectCount); m_ib_sizes.resize(_objectCount); m_vbs.resize(_objectCount); m_vbo_addrs.resize(_objectCount); m_vbo_sizes.resize(_objectCount); glGenBuffers(_objectCount, &*m_ibs.begin()); glGenBuffers(_objectCount, &*m_vbs.begin()); for (size_t u = 0; u < _objectCount; ++u) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibs[u]); glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), 0); glGetBufferParameterui64vNV(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_ib_addrs[u]); glMakeBufferResidentNV(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); m_ib_sizes[u] = _indices.size() * sizeof(UntexturedObjectsProblem::Index); glBindBuffer(GL_ARRAY_BUFFER, m_vbs[u]); glBufferStorage(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), 0); glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_vbo_addrs[u]); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); m_vbo_sizes[u] = _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex); } return glGetError() == GL_NO_ERROR; }
EXTERN_C_ENTER JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVShaderBufferLoad_glMakeBufferResidentNV(JNIEnv *__env, jclass clazz, jint target, jint access) { glMakeBufferResidentNVPROC glMakeBufferResidentNV = (glMakeBufferResidentNVPROC)tlsGetFunction(2099); UNUSED_PARAM(clazz) glMakeBufferResidentNV(target, access); }
bool initArrayBuffer() { glGenBuffers(1, &BufferName); glBindBuffer(GL_ARRAY_BUFFER, BufferName); glBufferData(GL_ARRAY_BUFFER, VertexSize, VertexData, GL_STATIC_DRAW); glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &Address); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); glBindBuffer(GL_ARRAY_BUFFER, 0); return glf::checkError("initArrayBuffer");; }
bool initBuffer() { glGenBuffers(buffer::MAX, BufferName); glBindBuffer(GL_ARRAY_BUFFER, BufferName[buffer::VERTEX]); glBufferData(GL_ARRAY_BUFFER, VertexSize, VertexData, GL_STATIC_DRAW); glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &Address); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4), 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); return true; }
int voxel_zread(int bricks, FILE * fptr) { unsigned char in[CHUNK]; unsigned char out[CHUNK]; z_stream strm = { .zalloc=Z_NULL, .zfree=Z_NULL, .opaque=Z_NULL, .avail_in=0, .next_in=Z_NULL }; int ret = inflateInit(&strm); if(ret != Z_OK) return ret; int prev_off = 0; int brick_size = B_SIZE*B_SIZE*B_SIZE*sizeof(float4); unsigned char *prev_buf = malloc(brick_size); do { strm.avail_in = fread(in, 1, CHUNK, fptr); if(ferror(fptr)) { ret = Z_ERRNO; goto zread_fail; } if(strm.avail_in == 0) break; strm.next_in = in; do { strm.avail_out = CHUNK; strm.next_out = out; ret = inflate(&strm, Z_NO_FLUSH); // assert(ret != Z_STREAM_ERROR); switch(ret) { case Z_NEED_DICT: ret = Z_DATA_ERROR; case Z_DATA_ERROR: case Z_MEM_ERROR: goto zread_fail; } int have = CHUNK - strm.avail_out; // pass data to loader int outoff = 0; if(have+prev_off > brick_size) { if(prev_off) { outoff = brick_size - prev_off; memcpy(prev_buf+prev_off, out, outoff); bp_add((float4*)prev_buf); prev_off = 0; } for(;outoff+brick_size <= have; outoff+= brick_size) bp_add((float4*)(out+outoff)); } if(outoff < have) { memcpy(prev_buf+prev_off, out+outoff, have - outoff); prev_off += have - outoff; if(prev_off >= brick_size) { bp_add((float4*)prev_buf); prev_off = 0; } } // strm.avail_out = 0; // end data loader } while(strm.avail_out == 0); } while(ret != Z_STREAM_END); inflateEnd(&strm); printf("zlib ok: inflated %d bricks.\n", brick_count-1); return 0; zread_fail: inflateEnd(&strm); free(prev_buf); printf("zlib fail = %d, bricks=%d\n", ret, brick_count); return ret; } int voxel_init(char *filename) { bPool = malloc(bPool_size); memset(bPool, 0, bPool_size); nPool = malloc(nPool_size); memset(nPool, 0, nPool_size); // Load file off of disk FILE *fptr = fopen(filename, "rb"); if(!fptr) { printf("Failed Opening SVO file \"%s\"\n", filename); return 0; } char check[4] = "VOCT"; int bricks, blocks; int zero; fread(check, 4, 1, fptr); fread(&blocks, 4, 1, fptr); fread(&bricks, 4, 1, fptr); fread(&zero, 4, 1, fptr); fread(nPool, blocks * 64, 1, fptr); int ret = voxel_zread(bricks, fptr); if(ret) { printf("zload failed\n"); } /* for(int i=0; i < bricks; i++) { int3 boff; int itmp = i % B_COUNT; boff.x = itmp; itmp = (i-boff.x)/B_COUNT; boff.y = itmp % B_COUNT; boff.z = (itmp-boff.y) / B_COUNT; F3MULS(boff, boff, B_SIZE); for(int z=0; z < B_SIZE; z++) for(int y=0; y < B_SIZE; y++) { fread(&bPool[boff.z+z][boff.y+y][boff.x], sizeof(float4)*B_SIZE, 1, fptr); } } */ // fread(bPool, 16*B_CUBE, 1, fptr); fclose(fptr); printf("Loaded %d blocks, %d bricks\n", blocks, bricks); printf("Error = \"%s\"\n", glError(glGetError())); free_vram(); // Send the brick pool to the GPU glEnable(GL_TEXTURE_3D); glGenTextures(1, &brick_tex); glBindTexture(GL_TEXTURE_3D, brick_tex); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); printf("Error = \"%s\"\n", glError(glGetError())); glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F, B_EDGE, B_EDGE, B_EDGE, 0, GL_RGBA, GL_FLOAT, bPool); printf("Error = \"%s\"\n", glError(glGetError())); glBindTexture(GL_TEXTURE_3D, 0); printf("Error = \"%s\"\n", glError(glGetError())); free_vram(); // load the node pool onto the GPU glGenBuffers(1, &node_pool); glBindBuffer(GL_ARRAY_BUFFER, node_pool); glBufferData(GL_ARRAY_BUFFER, nPool_size, nPool, GL_DYNAMIC_DRAW); glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &nodepool_devptr); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); glBindBuffer(GL_ARRAY_BUFFER, 0); printf("Error = \"%s\"\n", glError(glGetError())); prepare_shader(); return 1; }
void GLGeometry::refresh() { Assert(m_id[0] != 0 && m_id[1] != 0); m_stride = 3; if (m_mesh->hasVertexNormals()) m_stride += 3; if (m_mesh->hasVertexTexcoords()) m_stride += 2; if (m_mesh->hasUVTangents()) m_stride += 3; if (m_mesh->hasVertexColors()) m_stride += 3; m_stride *= sizeof(GLfloat); size_t vertexCount = m_mesh->getVertexCount(), triCount = m_mesh->getTriangleCount(); m_size[EVertexID] = (GLuint) (vertexCount * m_stride); m_size[EIndexID] = (GLuint) (triCount * sizeof(GLuint) * 3); Log(ETrace, "Uploading a GPU geometry object (\"%s\", " SIZE_T_FMT " vertices, " SIZE_T_FMT " triangles, %s)", getName().c_str(), vertexCount, triCount, memString(m_size[EVertexID] + m_size[EIndexID]).c_str()); GLfloat *vertices = new GLfloat[vertexCount * m_stride/sizeof(GLfloat)]; GLuint *indices = (GLuint *) m_mesh->getTriangles(); const Point *sourcePositions = m_mesh->getVertexPositions(); const Normal *sourceNormals = m_mesh->getVertexNormals(); const Point2 *sourceTexcoords = m_mesh->getVertexTexcoords(); const Color3 *sourceColors = m_mesh->getVertexColors(); Vector *sourceTangents = NULL; if (m_mesh->hasUVTangents()) { /* Convert into per-vertex tangents */ const TangentSpace *triTangents = m_mesh->getUVTangents(); sourceTangents = new Vector[vertexCount]; uint32_t *count = new uint32_t[vertexCount]; memset(sourceTangents, 0, sizeof(Vector)*vertexCount); for (size_t i=0; i<triCount; ++i) { const Triangle &tri = m_mesh->getTriangles()[i]; const TangentSpace &tangents = triTangents[i]; for (int j=0; j<3; ++j) { sourceTangents[tri.idx[j]] += tangents.dpdu; ++count[tri.idx[j]]; } } for (size_t i=0; i<vertexCount; ++i) { if (count[i] == 0) continue; sourceTangents[i] /= (Float) count[i]; } delete[] count; } size_t pos = 0; for (size_t i=0; i<vertexCount; ++i) { vertices[pos++] = (GLfloat) sourcePositions[i].x; vertices[pos++] = (GLfloat) sourcePositions[i].y; vertices[pos++] = (GLfloat) sourcePositions[i].z; if (sourceNormals) { vertices[pos++] = (GLfloat) sourceNormals[i].x; vertices[pos++] = (GLfloat) sourceNormals[i].y; vertices[pos++] = (GLfloat) sourceNormals[i].z; } if (sourceTexcoords) { vertices[pos++] = (GLfloat) sourceTexcoords[i].x; vertices[pos++] = (GLfloat) sourceTexcoords[i].y; } if (sourceTangents) { vertices[pos++] = (GLfloat) sourceTangents[i].x; vertices[pos++] = (GLfloat) sourceTangents[i].y; vertices[pos++] = (GLfloat) sourceTangents[i].z; } if (sourceColors) { vertices[pos++] = (GLfloat) sourceColors[i][0]; vertices[pos++] = (GLfloat) sourceColors[i][1]; vertices[pos++] = (GLfloat) sourceColors[i][2]; } } Assert(pos * sizeof(GLfloat) == m_stride * vertexCount); bind(); glBufferData(GL_ARRAY_BUFFER, m_size[EVertexID], vertices, GL_STATIC_DRAW); if (GLEW_NV_vertex_buffer_unified_memory) { glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_addr[EVertexID]); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); } glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size[EIndexID], indices, GL_STATIC_DRAW); if (GLEW_NV_vertex_buffer_unified_memory) { glGetBufferParameterui64vNV(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_addr[EIndexID]); glMakeBufferResidentNV(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); } unbind(); delete[] vertices; if (sourceTangents) delete[] sourceTangents; }
// -------------------------------------------------------------------------------------------------------------------- bool UntexturedObjectsGLBindlessIndirect::Init(const std::vector<UntexturedObjectsProblem::Vertex>& _vertices, const std::vector<UntexturedObjectsProblem::Index>& _indices, size_t _objectCount) { if (glBufferStorage == nullptr) { console::warn("Unable to initialize solution '%s', glBufferStorage() unavailable.", GetName().c_str()); return false; } if (glGetBufferParameterui64vNV == nullptr || glMakeBufferResidentNV == nullptr) { console::warn("Unable to initialize solution '%s', GL_NV_shader_buffer_load unavailable.", GetName().c_str()); return false; } if (!UntexturedObjectsSolution::Init(_vertices, _indices, _objectCount)) { return false; } // Program const char* kUniformNames[] = { "ViewProjection", "World", nullptr }; m_prog = CreateProgramT("cubes_gl_bindless_indirect_vs.glsl", "cubes_gl_bindless_indirect_fs.glsl", kUniformNames, &mUniformLocation); if (m_prog == 0) { console::warn("Unable to initialize solution '%s', shader compilation/linking failed.", GetName().c_str()); return false; } m_ibs.resize(_objectCount); m_ib_addrs.resize(_objectCount); m_ib_sizes.resize(_objectCount); m_vbs.resize(_objectCount); m_vbo_addrs.resize(_objectCount); m_vbo_sizes.resize(_objectCount); m_commands.resize(_objectCount); glGenBuffers(_objectCount, &*m_ibs.begin()); glGenBuffers(_objectCount, &*m_vbs.begin()); for (size_t u = 0; u < _objectCount; ++u) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ibs[u]); glBufferStorage(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(UntexturedObjectsProblem::Index), &*_indices.begin(), 0); glGetBufferParameterui64vNV(GL_ELEMENT_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_ib_addrs[u]); glMakeBufferResidentNV(GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY); m_ib_sizes[u] = _indices.size() * sizeof(UntexturedObjectsProblem::Index); glBindBuffer(GL_ARRAY_BUFFER, m_vbs[u]); glBufferStorage(GL_ARRAY_BUFFER, _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex), &*_vertices.begin(), 0); glGetBufferParameterui64vNV(GL_ARRAY_BUFFER, GL_BUFFER_GPU_ADDRESS_NV, &m_vbo_addrs[u]); glMakeBufferResidentNV(GL_ARRAY_BUFFER, GL_READ_ONLY); m_vbo_sizes[u] = _vertices.size() * sizeof(UntexturedObjectsProblem::Vertex); } glGenBuffers(1, &m_transform_buffer); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_transform_buffer); glBufferStorage(GL_SHADER_STORAGE_BUFFER, _objectCount * 64, nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT); m_transform_ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, _objectCount * 64, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); glGenBuffers(1, &m_cmd_buffer); glBindBuffer(GL_DRAW_INDIRECT_BUFFER, m_cmd_buffer); glBufferStorage(GL_DRAW_INDIRECT_BUFFER, _objectCount * sizeof(Command), nullptr, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_DYNAMIC_STORAGE_BIT); m_cmd_ptr = glMapBufferRange(GL_DRAW_INDIRECT_BUFFER, 0, _objectCount * sizeof(Command), GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); m_queries.resize(4); glGenQueries(kQueryCount, &*m_queries.begin()); return glGetError() == GL_NO_ERROR; }