XCamReturn GLBuffer::flush_map () { if (!_mapped_range.is_mapped ()) return XCAM_RETURN_ERROR_ORDER; XCAM_FAIL_RETURN ( ERROR, _mapped_range.flags & GL_MAP_FLUSH_EXPLICIT_BIT, XCAM_RETURN_ERROR_GLES, "GL buffer flush_map buf:%d failed, invalid flags(:%d)", _buf_id, _mapped_range.flags); XCamReturn ret = bind (); XCAM_FAIL_RETURN ( ERROR, xcam_ret_is_ok (ret), ret, "GL bind buffer failed, buf_id:%d", _buf_id); glFlushMappedBufferRange (_target, _mapped_range.offset, _mapped_range.len); GLenum error = gl_error (); XCAM_FAIL_RETURN ( ERROR, error == GL_NO_ERROR, XCAM_RETURN_ERROR_GLES, "GL buffer flush_map buf:%d failed, error flag: %s", _buf_id, gl_error_string (error)); return XCAM_RETURN_NO_ERROR; }
// Buffer update using glMapBufferRange bool initArrayBuffer() { // Generate a buffer object glGenBuffers(1, &BufferName); // Bind the buffer for use glBindBuffer(GL_ARRAY_BUFFER, BufferName); // Reserve buffer memory but don't copy the values glBufferData( GL_ARRAY_BUFFER, PositionSize, 0, GL_STATIC_DRAW); // Copy the vertex data in the buffer, in this sample for the whole range of data. // It doesn't required to be the buffer size but pointers require no memory overlapping. GLvoid* Data = glMapBufferRange( GL_ARRAY_BUFFER, 0, // Offset PositionSize, // Size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); memcpy(Data, PositionData, PositionSize); // Explicitly send the data to the graphic card. glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, PositionSize); glUnmapBuffer(GL_ARRAY_BUFFER); // Unbind the buffer glBindBuffer(GL_ARRAY_BUFFER, 0); return glf::checkError("initArrayBuffer"); }
void Unmap() { if (m_texture_storage) { glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size); } else { glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); } }
void display() { // Update of the array buffer glm::mat4 Perspective = glm::perspective(45.0f, float(Window.Size.x) / float(Window.Size.y), 0.1f, 100.0f); glm::mat4 ViewTranslate = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y * 2.0 - 0.0)); glm::mat4 ViewRotateX = glm::rotate(ViewTranslate, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f)); glm::mat4 View = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f)); glm::mat4 Model = glm::mat4(1.0f); glm::mat4 MVP = Perspective * View * Model; for(GLsizei i = (0); i < VertexCount; ++i) (Pointer + i)->Position = MVP * VertexData[i].Position; glBindBuffer(GL_ARRAY_BUFFER, BufferName[buffer::VERTEX]); glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, sizeof(glf::vertex_v4fv2f) * 4); glBindBuffer(GL_ARRAY_BUFFER, 0); glViewportIndexedf(0, 0, 0, GLfloat(Window.Size.x), GLfloat(Window.Size.y)); glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]); // Bind rendering objects glBindProgramPipeline(PipelineName); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureName); glBindVertexArray(VertexArrayName); // Make sure the array buffer is uploaded glMemoryBarrier(GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT); glDrawElementsInstancedBaseVertexBaseInstance( GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 1, 0, 0); glf::swapBuffers(); }
u32 Stream(u32 size, const void* src) override { AllocMemory(size); u32 iter = m_iterator; m_iterator += size; std::memcpy(m_pointer + iter, src, size); if (!coherent) glFlushMappedBufferRange(m_buffertype, iter, size); return iter; }
inline void flush_buffer_range(BufferType target, ptrdiff_t offset, ptrdiff_t length) { ARC_GL_CLEAR_ERRORS(); glFlushMappedBufferRange((GLenum)target,offset,length); #ifdef ARC_GL_DEBUG_OBSERVE gl_observer->flush_buffer_range(target, offset, length); #endif ARC_GL_CHECK_FOR_ERRORS(); }
u32 Stream(u32 size, const void* src) override { AllocMemory(size); u32 iter = m_iterator; m_iterator += size; u8* pointer = (u8*)glMapBufferRange(m_buffertype, iter, size, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT); std::memcpy(pointer, src, size); glFlushMappedBufferRange(m_buffertype, 0, size); glUnmapBuffer(m_buffertype); return iter; }
void NvSharedVBOGL::EndUpdate() { #if !USE_PERSISTENT_MAPPING if (0 == m_vbo) { return; } glBindBuffer(GL_ARRAY_BUFFER, m_vbo); glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, m_dataSize); glUnmapBuffer(GL_ARRAY_BUFFER); #endif m_fences[m_index] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); }
u32 Stream(u32 size, const void* src) override { if (m_iterator + size >= m_size) { glBufferData(m_buffertype, m_size, nullptr, GL_STREAM_DRAW); m_iterator = 0; } u32 iter = m_iterator; m_iterator += size; u8* pointer = (u8*)glMapBufferRange(m_buffertype, iter, size, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT); std::memcpy(pointer, src, size); glFlushMappedBufferRange(m_buffertype, 0, size); glUnmapBuffer(m_buffertype); return iter; }
void base::frame_context::flush_scene_data() { glBindBuffer(GL_TEXTURE_BUFFER, _scene_vbo); if(_mode != ModeBufferData && _mode != ModeBufferSubData) { if(_mode == ModeFlushExplicit && _scene_data_ptr_size > 0) { glFlushMappedBufferRange(GL_TEXTURE_BUFFER, 0, _scene_data_ptr_size); } glUnmapBuffer(GL_TEXTURE_BUFFER); } else if(_mode == ModeBufferData) { glBufferData(GL_TEXTURE_BUFFER, _scene_data_ptr_size, 0, GL_STREAM_DRAW); glBufferSubData(GL_TEXTURE_BUFFER, 0, _scene_data_ptr_size, _scene_data_ptr); } else if(_mode == ModeBufferSubData) { glBufferSubData(GL_TEXTURE_BUFFER, 0, _scene_data_ptr_size, _scene_data_ptr); } glBindBuffer(GL_TEXTURE_BUFFER, 0); }
void base::frame_context::flush_canvas_data() { const int size = (_elements - _elements_begin) * sizeof(glm::vec4) * 3; glBindBuffer(GL_TEXTURE_BUFFER, _canvas_vbo); if(_mode != ModeBufferData && _mode != ModeBufferSubData) { if(_mode == ModeFlushExplicit && _elements - _elements_begin > 0) { glFlushMappedBufferRange(GL_TEXTURE_BUFFER, 0, size); } glUnmapBuffer(GL_TEXTURE_BUFFER); } else if(_mode == ModeBufferData) { glBufferData(GL_TEXTURE_BUFFER, size, 0, GL_STREAM_DRAW); glBufferSubData(GL_TEXTURE_BUFFER, 0, size, _elements_begin); } else if(_mode == ModeBufferSubData) { glBufferSubData(GL_TEXTURE_BUFFER, 0, size, _elements_begin); } glBindBuffer(GL_TEXTURE_BUFFER, 0); }
void display() { { // Compute the MVP (Model View Projection matrix) float Aspect = (Window.Size.x * 0.33f) / (Window.Size.y * 0.50f); glm::mat4 Projection = glm::perspective(45.0f, Aspect, 0.1f, 100.0f); glm::mat4 ViewTranslateZ = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y)); glm::mat4 ViewRotateX = glm::rotate(ViewTranslateZ, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f)); glm::mat4 ViewRotateY = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f)); glm::mat4 View = ViewRotateY; glm::mat4 Model = glm::mat4(1.0f); glm::mat4 MVP = Projection * View * Model; *UniformPointer = MVP; } glFlushMappedBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4)); glClearBufferfv(GL_COLOR, 0, &glm::vec4(1.0f, 0.5f, 0.0f, 1.0f)[0]); glBindProgramPipeline(PipelineName); glBindBuffersBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, 1, &BufferName[buffer::TRANSFORM]); glBindTextures(glf::semantic::sampler::DIFFUSE, 1, &TextureName); glBindVertexArray(VertexArrayName); glBindVertexBuffer(glf::semantic::buffer::STATIC, BufferName[buffer::VERTEX], 0, GLsizei(sizeof(vertex))); for(std::size_t Index = 0; Index < viewport::MAX; ++Index) { glViewportIndexedf(0, Viewport[Index].x, Viewport[Index].y, Viewport[Index].z, Viewport[Index].w); glBindSamplers(0, 1, &SamplerName[Index]); glDrawArraysInstanced(GL_TRIANGLES, 0, VertexCount, 1); } glf::checkError("display"); glf::swapBuffers(); }
void RenderSystem::mapBuffer(RenderSystem::BufferType type, intptr_t offset, size_t size, void* data) { int gl_type = bufferTypeToGL(type); CROSS_GL_ASSERT(); void* buf_data = glMapBufferRange( gl_type, offset, size, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT ); CROSS_GL_ASSERT(); memcpy(buf_data, data, size); glFlushMappedBufferRange(gl_type, offset, size); CROSS_GL_ASSERT(); }
void GL3PlusHardwareUniformBuffer::unlockImpl(void) { OGRE_CHECK_GL_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, mBufferId)); if (mUsage & HBU_WRITE_ONLY) { OGRE_CHECK_GL_ERROR(glFlushMappedBufferRange(GL_UNIFORM_BUFFER, mLockStart, mLockSize)); } GLboolean mapped; OGRE_CHECK_GL_ERROR(mapped = glUnmapBuffer(GL_UNIFORM_BUFFER)); if(!mapped) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload", "GL3PlusHardwareUniformBuffer::unlock"); } OGRE_CHECK_GL_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, 0)); mIsLocked = false; }
void GL3PlusHardwareVertexBuffer::unlockImpl(void) { if (mLockedToScratch) { if (mScratchUploadOnUnlock) { // have to write the data back to vertex buffer writeData(mScratchOffset, mScratchSize, mScratchPtr, mScratchOffset == 0 && mScratchSize == getSizeInBytes()); } // deallocate from scratch buffer static_cast<GL3PlusHardwareBufferManager*>( HardwareBufferManager::getSingletonPtr())->deallocateScratch(mScratchPtr); mLockedToScratch = false; } else { OGRE_CHECK_GL_ERROR(glBindBuffer(GL_ARRAY_BUFFER, mBufferId)); if (mUsage & HBU_WRITE_ONLY) { OGRE_CHECK_GL_ERROR(glFlushMappedBufferRange(GL_ARRAY_BUFFER, mLockStart, mLockSize)); } GLboolean mapped; OGRE_CHECK_GL_ERROR(mapped = glUnmapBuffer(GL_ARRAY_BUFFER)); if(!mapped) { OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, "Buffer data corrupted, please reload", "GL3PlusHardwareVertexBuffer::unlock"); } OGRE_CHECK_GL_ERROR(glBindBuffer(GL_ARRAY_BUFFER, 0)); } mIsLocked = false; }
void Buffer::SetBufferSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { CHECK_ASSERT(offset + size <= bufferSize_); #if !defined(ANDROID) && !defined(EMSCRIPTEN) if (Graphics::GetPtr()->HasMapBufferRange()) { void* old_data = glMapBufferRange(type_, offset, size, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT | GL_MAP_UNSYNCHRONIZED_BIT); CHECK_ASSERT(old_data); memcpy(old_data, data, size); glFlushMappedBufferRange(type_, offset, size); CHECK_CONDITION(glUnmapBuffer(type_)); } else #endif { glBufferSubData(type_, offset, size, data); } }
// Buffer update using glMapBufferRange bool initBuffer() { // Generate a buffer object glGenBuffers(buffer::MAX, &BufferName[0]); // Bind the buffer for use glBindBuffer(GL_ARRAY_BUFFER, BufferName[buffer::ARRAY]); // Reserve buffer memory but don't copy the values glBufferData( GL_ARRAY_BUFFER, PositionSize, 0, GL_STATIC_DRAW); // Copy the vertex data in the buffer, in this sample for the whole range of data. // It doesn't required to be the buffer size but pointers require no memory overlapping. GLvoid* Data = glMapBufferRange( GL_ARRAY_BUFFER, 0, // Offset PositionSize, // Size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); memcpy(Data, PositionData, PositionSize); // Explicitly send the data to the graphic card. glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, PositionSize); glUnmapBuffer(GL_ARRAY_BUFFER); // Unbind the buffer glBindBuffer(GL_ARRAY_BUFFER, 0); // Copy buffer glBindBuffer(GL_ARRAY_BUFFER, BufferName[buffer::COPY]); glBufferData(GL_ARRAY_BUFFER, PositionSize, 0, GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_COPY_READ_BUFFER, BufferName[buffer::ARRAY]); glBindBuffer(GL_COPY_WRITE_BUFFER, BufferName[buffer::COPY]); glCopyBufferSubData( GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, PositionSize); glBindBuffer(GL_COPY_READ_BUFFER, 0); glBindBuffer(GL_COPY_WRITE_BUFFER, 0); GLint UniformBlockSize = 0; { glGetActiveUniformBlockiv( ProgramName, UniformTransform, GL_UNIFORM_BLOCK_DATA_SIZE, &UniformBlockSize); glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::TRANSFORM]); glBufferData(GL_UNIFORM_BUFFER, UniformBlockSize, 0, GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } { glm::vec4 Diffuse(1.0f, 0.5f, 0.0f, 1.0f); glGetActiveUniformBlockiv( ProgramName, UniformMaterial, GL_UNIFORM_BLOCK_DATA_SIZE, &UniformBlockSize); glBindBuffer(GL_UNIFORM_BUFFER, BufferName[buffer::MATERIAL]); glBufferData(GL_UNIFORM_BUFFER, UniformBlockSize, &Diffuse[0], GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); } return this->checkError("initBuffer"); }
void display() { { // Compute the MVP (Model View Projection matrix) float Aspect = (Window.Size.x * 0.50f) / (Window.Size.y * 0.50f); glm::mat4 Projection = glm::perspective(45.0f, Aspect, 0.1f, 100.0f); glm::mat4 ViewTranslateZ = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, -Window.TranlationCurrent.y)); glm::mat4 ViewRotateX = glm::rotate(ViewTranslateZ, Window.RotationCurrent.y, glm::vec3(1.f, 0.f, 0.f)); glm::mat4 ViewRotateY = glm::rotate(ViewRotateX, Window.RotationCurrent.x, glm::vec3(0.f, 1.f, 0.f)); glm::mat4 View = ViewRotateY; glm::mat4 Model = glm::mat4(1.0f); glm::mat4 MVP = Projection * View * Model; *UniformPointer = MVP; } glFlushMappedBufferRange(GL_UNIFORM_BUFFER, 0, sizeof(glm::mat4)); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glViewportIndexedf(0, 0, 0, GLfloat(Window.Size.x), GLfloat(Window.Size.y)); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName); float Depth(1.0f); glm::u8vec4 ColorClear(255, 127, 0, 255); glm::u8vec4 ColorTex(0, 127, 255, 255); glClearBufferfv(GL_DEPTH , 0, &Depth); glClearTexImage(TextureName[texture::COLORBUFFER], 0, GL_RGBA, GL_UNSIGNED_BYTE, &ColorClear); glClearTexSubImage(TextureName[texture::COLORBUFFER], 0, 64, 64, 0, 64, 64, 1, GL_RGBA, GL_UNSIGNED_BYTE, &ColorTex); glClearTexSubImage(TextureName[texture::COLORBUFFER], 0, 256, 0, 0, 64, 64, 1, GL_RGBA, GL_UNSIGNED_BYTE, &ColorTex); glClearTexSubImage(TextureName[texture::COLORBUFFER], 0, 128, 384, 0, 64, 64, 1, GL_RGBA, GL_UNSIGNED_BYTE, &ColorTex); glClearTexSubImage(TextureName[texture::COLORBUFFER], 0, 512, 256, 0, 64, 64, 1, GL_RGBA, GL_UNSIGNED_BYTE, &ColorTex); // Bind rendering objects glBindProgramPipeline(PipelineName[pipeline::TEXTURE]); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, TextureName[texture::DIFFUSE]); glBindVertexArray(VertexArrayName[pipeline::TEXTURE]); glBindVertexBuffer(glf::semantic::buffer::STATIC, BufferName[buffer::VERTEX], 0, GLsizei(sizeof(glf::vertex_v2fv2f))); glBindBufferBase(GL_UNIFORM_BUFFER, glf::semantic::uniform::TRANSFORM0, BufferName[buffer::TRANSFORM]); glDrawElementsInstancedBaseVertexBaseInstance( GL_TRIANGLES, ElementCount, GL_UNSIGNED_SHORT, 0, 2, 0, 0); glDisable(GL_DEPTH_TEST); glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindProgramPipeline(PipelineName[pipeline::SPLASH]); glActiveTexture(GL_TEXTURE0); glBindVertexArray(VertexArrayName[pipeline::SPLASH]); glBindTexture(GL_TEXTURE_2D, TextureName[texture::COLORBUFFER]); glDrawArraysInstanced(GL_TRIANGLES, 0, 3, 1); glf::swapBuffers(); }
// AP - Function that I was using to test pbo unmap timing with different options, should never be called in production. Also it exits at the end. void pbotiming(GLuint pbo) { int size = 5000000; void * p; glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); { glBufferData(GL_PIXEL_UNPACK_BUFFER, size, 0, GL_STREAM_DRAW); p = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); if(!p) { std::cerr << "Invalid map." << std::endl; } memset(p,0x00,size); struct timeval start, end; gettimeofday(&start,NULL); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); gettimeofday(&end,NULL); std::cerr << "Full unmap time: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 1000000.0) << std::endl; p = glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); memset(p,0x01,size); float segments = 5.0; int ssize = (int)(size / segments); if(segments * ssize < size) { ssize++; } int copied = 0; for(int i = 0; i < segments; i++) { #ifndef WIN32 int copy = std::min(size - copied,ssize); #else int copy = min(size - copied,ssize); #endif std::cerr << "Offset: " << copied << " length: " << copy << std::endl; struct timeval fstart, fend; gettimeofday(&fstart,NULL); glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER,copied,copy); //glFinish(); gettimeofday(&fend,NULL); std::cerr << "Segment flush time: " << (fend.tv_sec - fstart.tv_sec) + ((fend.tv_usec - fstart.tv_usec)/ 1000000.0) << std::endl; copied += copy; #ifndef WIN32 sleep(1); #else Sleep(1000); #endif } gettimeofday(&start,NULL); glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); gettimeofday(&end,NULL); std::cerr << "Final unmap time: " << (end.tv_sec - start.tv_sec) + ((end.tv_usec - start.tv_usec)/ 1000000.0) << std::endl; } glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); exit(0); }
/* ============== Tess_UpdateVBOs Tr3B: update the default VBO to replace the client side vertex arrays ============== */ void Tess_UpdateVBOs() { GLimp_LogComment( "--- Tess_UpdateVBOs( ) ---\n" ); GL_CheckErrors(); // update the default VBO if ( tess.numVertexes > 0 && tess.numVertexes <= SHADER_MAX_VERTEXES ) { GLsizei size = tess.numVertexes * sizeof( shaderVertex_t ); GL_CheckErrors(); if ( r_logFile->integer ) { GLimp_LogComment( va( "glBufferSubData( vbo = '%s', numVertexes = %i )\n", tess.vbo->name, tess.numVertexes ) ); } if( !glConfig2.mapBufferRangeAvailable ) { R_BindVBO( tess.vbo ); glBufferSubData( GL_ARRAY_BUFFER, 0, size, tess.verts ); } else { R_BindVBO( tess.vbo ); if( glConfig2.bufferStorageAvailable && glConfig2.syncAvailable ) { GLsizei offset = tess.vertexBase * sizeof( shaderVertex_t ); glFlushMappedBufferRange( GL_ARRAY_BUFFER, offset, size ); } else { glFlushMappedBufferRange( GL_ARRAY_BUFFER, 0, size ); glUnmapBuffer( GL_ARRAY_BUFFER ); } tess.vertexBase = tess.vertsWritten; tess.vertsWritten += tess.numVertexes; tess.verts = nullptr; } } GL_CheckErrors(); // update the default IBO if ( tess.numIndexes > 0 && tess.numIndexes <= SHADER_MAX_INDEXES ) { GLsizei size = tess.numIndexes * sizeof( glIndex_t ); if( !glConfig2.mapBufferRangeAvailable ) { R_BindIBO( tess.ibo ); glBufferSubData( GL_ELEMENT_ARRAY_BUFFER, 0, size, tess.indexes ); } else { R_BindIBO( tess.ibo ); if( glConfig2.bufferStorageAvailable && glConfig2.syncAvailable ) { GLsizei offset = tess.indexBase * sizeof( glIndex_t ); glFlushMappedBufferRange( GL_ELEMENT_ARRAY_BUFFER, offset, size ); } else { glFlushMappedBufferRange( GL_ELEMENT_ARRAY_BUFFER, 0, size ); glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER ); } tess.indexBase = tess.indexesWritten; tess.indexesWritten += tess.numIndexes; tess.indexes = nullptr; } } GL_CheckErrors(); }
void Unmap() { glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset[m_current_pbo], m_size); }
void Unmap() { glFlushMappedBufferRange(GL_PIXEL_UNPACK_BUFFER, m_offset, m_size); }
void Unmap(u32 used_size) override { if (!coherent) glFlushMappedBufferRange(m_buffertype, m_iterator, used_size); m_iterator += used_size; }
void Unmap(u32 used_size) override { glFlushMappedBufferRange(m_buffertype, 0, used_size); glUnmapBuffer(m_buffertype); m_iterator += used_size; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_ARBMapBufferRange_nglFlushMappedBufferRange(JNIEnv *env, jclass clazz, jint target, jlong offset, jlong length, jlong function_pointer) { glFlushMappedBufferRangePROC glFlushMappedBufferRange = (glFlushMappedBufferRangePROC)((intptr_t)function_pointer); glFlushMappedBufferRange(target, offset, length); }
static void testBufferStorage(void) { if (!GLAD_GL_VERSION_4_4 && !glfwExtensionSupported("GL_ARB_buffer_storage")) { fprintf(stderr, "error: GL_ARB_buffer_storage not supported\n"); glfwTerminate(); exit(EXIT_SKIP); } GLbitfield map_trace_explicit_bit = 0; if (glfwExtensionSupported("GL_VMWX_map_buffer_debug")) { glNotifyMappedBufferRangeVMWX = (PFNGLNOTIFYMAPPEDBUFFERRANGEVMWXPROC)glfwGetProcAddress("glNotifyMappedBufferRangeVMWX"); assert(glNotifyMappedBufferRangeVMWX); map_trace_explicit_bit = GL_MAP_NOTIFY_EXPLICIT_BIT_VMWX; } GLuint buffer = 0; glGenBuffers(1, &buffer); glBindBuffer(target, buffer); GLsizeiptr size = 1000; void *data = malloc(size); memset(data, 0, size); while ((glGetError() != GL_NO_ERROR)) ; glBufferStorage(target, size, data, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | map_trace_explicit_bit); free(data); GLenum error = glGetError(); switch (error) { case GL_NO_ERROR: break; case GL_OUT_OF_MEMORY: exit(EXIT_SKIP); default: exit(EXIT_FAILURE); } GLubyte *map; // straightforward mapping map = (GLubyte *)glMapBufferRange(target, 100, 100, GL_MAP_WRITE_BIT); memset(map, 1, 100); glUnmapBuffer(target); // persistent mapping w/ explicit flush map = (GLubyte *)glMapBufferRange(target, 200, 300, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_FLUSH_EXPLICIT_BIT); memset(map + 20, 2, 30); glFlushMappedBufferRange(target, 20, 30); memset(map + 50, 3, 50); glFlushMappedBufferRange(target, 50, 50); glUnmapBuffer(target); // persistent & coherent mapping map = (GLubyte *)glMapBufferRange(target, 500, 100, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT | map_trace_explicit_bit); memset(map + 20, 4, 30); glNotifyMappedBufferRangeVMWX(map + 20, 30); memset(map + 50, 5, 50); glNotifyMappedBufferRangeVMWX(map + 50, 50); glUnmapBuffer(target); glBindBuffer(target, 0); glDeleteBuffers(1, &buffer); }