From 5b6875ca4a70055bcf93cf97c554e6d52088c012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 8 Jan 2016 23:41:30 +0100 Subject: [PATCH] Implemented glMemoryBarrier() from ARB_shader_image_load_store. And also the ByRegion variant from ES3.1. --- doc/opengl-mapping.dox | 2 +- doc/opengl-support.dox | 2 +- src/Magnum/Renderer.h | 119 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index 90d45f817..5c8ce87df 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -264,7 +264,7 @@ OpenGL function | Matching API @fn_gl_extension{MakeTextureHandleNonResident,ARB,bindless_texture} | | @fn_gl{MapBuffer}, \n `glMapNamedBuffer()`, \n @fn_gl_extension{MapNamedBuffer,EXT,direct_state_access}, \n @fn_gl{MapBufferRange}, \n `glMapNamedBufferRange()`, \n @fn_gl_extension{MapNamedBufferRange,EXT,direct_state_access}, \n @fn_gl{UnmapBuffer}, \n `glUnmapNamedBuffer()`, \n @fn_gl_extension{UnmapNamedBuffer,EXT,direct_state_access} | @ref Buffer::map(), @ref Buffer::unmap() @fn_gl_extension{MapBufferSubData,CHROMIUM,map_sub}, @fn_gl_extension{UnmapBufferSubData,CHROMIUM,map_sub} | @ref Buffer::mapSub(), @ref Buffer::unmapSub() -@fn_gl{MemoryBarrier}, \n `glMemoryBarrierByRegion()` | | +@fn_gl{MemoryBarrier}, \n `glMemoryBarrierByRegion()` | @ref Renderer::setMemoryBarrier(), \n @ref Renderer::setMemoryBarrierByRegion() @fn_gl{MinSampleShading} | | @fn_gl{MultiDrawArrays}, \n @fn_gl{MultiDrawElements}, \n @fn_gl{MultiDrawElementsBaseVertex} | @ref MeshView::draw(AbstractShaderProgram&, std::initializer_list>) @fn_gl_extension{MultiDrawArraysIndirectCount,ARB,indirect_parameters}, \n @fn_gl_extension{MultiDrawElementsIndirectCount,ARB,indirect_parameters} | | diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index cfa0c079e..1128287ac 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -216,7 +216,7 @@ GLSL 4.40 | done Extension | Status ------------------------------------------- | ------ GLSL 4.50 | done -@extension{ARB,ES3_1_compatibility} | | +@extension{ARB,ES3_1_compatibility} | done @extension{ARB,clip_control} | | @extension{ARB,conditional_render_inverted} | done @extension{ARB,cull_distance} | | diff --git a/src/Magnum/Renderer.h b/src/Magnum/Renderer.h index e7bddd740..b93098cb6 100644 --- a/src/Magnum/Renderer.h +++ b/src/Magnum/Renderer.h @@ -1207,7 +1207,7 @@ class MAGNUM_EXPORT Renderer { /*@}*/ #endif - /** @{ @name Renderer management */ + /** @{ @name Renderer synchronization */ /** * @brief Flush the pipeline @@ -1224,6 +1224,123 @@ class MAGNUM_EXPORT Renderer { */ static void finish() { glFinish(); } + #if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) + /** + * @brief Memory barrier + * + * @see @ref MemoryBarriers, @ref setMemoryBarrier(), + * @ref setMemoryBarrierByRegion() + * @requires_gl42 Extension @extension{ARB,shader_image_load_store} + * @requires_gles31 Shader image load/store is not available in OpenGL + * ES 3.0 and older. + * @requires_gles Shader image load/store is not available in WebGL. + */ + enum class MemoryBarrier: GLbitfield { + /** Vertex data */ + VertexAttributeArray = GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT, + + /** Vertex indices */ + ElementArray = GL_ELEMENT_ARRAY_BARRIER_BIT, + + /** Uniforms */ + Uniform = GL_UNIFORM_BARRIER_BIT, + + /** Texture fetches */ + TextureFetch = GL_TEXTURE_FETCH_BARRIER_BIT, + + /** Shader image access */ + ShaderImageAccess = GL_SHADER_IMAGE_ACCESS_BARRIER_BIT, + + /** Indirect command data */ + Command = GL_COMMAND_BARRIER_BIT, + + /** Pixel buffer data */ + PixelBuffer = GL_PIXEL_BUFFER_BARRIER_BIT, + + /** Texture updates */ + TextureUpdate = GL_TEXTURE_UPDATE_BARRIER_BIT, + + /** Buffer updates */ + BufferUpdate = GL_BUFFER_UPDATE_BARRIER_BIT, + + /** Framebuffer operations */ + Framebuffer = GL_FRAMEBUFFER_BARRIER_BIT, + + /** Transform feedback data */ + TransformFeedback = GL_TRANSFORM_FEEDBACK_BARRIER_BIT, + + /** Atomic counters */ + AtomicCounter = GL_ATOMIC_COUNTER_BARRIER_BIT, + + /** + * Shader storage data + * @requires_gl43 Extension @extension{ARB,shader_storage_buffer_object} + * @requires_gles31 Shader storage is not available in OpenGL ES + * 3.0 and older. + * @requires_gles Shader storage is not available in WebGL. + */ + ShaderStorage = GL_ATOMIC_COUNTER_BARRIER_BIT + }; + + /** + * @brief Memory barriers + * + * @see @ref setMemoryBarrier(), @ref setMemoryBarrierByRegion() + * @requires_gl42 Extension @extension{ARB,shader_image_load_store} + * @requires_gles31 Shader image load/store is not available in OpenGL + * ES 3.0 and older. + * @requires_gles Shader image load/store is not available in WebGL. + */ + typedef Containers::EnumSet MemoryBarriers; + + /** + * @brief Set memory barrier + * + * Calling the function ensures that operations on particular data + * after the barrier will reflect all data modifications before the + * barrier. + * @see @ref setMemoryBarrierByRegion(), @fn_gl{MemoryBarrier} + * @requires_gl42 Extension @extension{ARB,shader_image_load_store} + * @requires_gles31 Shader load/store is not available in OpenGL ES 3.0 and older. + * @requires_gles Shader load/store is not available in WebGL. + */ + void setMemoryBarrier(MemoryBarriers barriers) { + glMemoryBarrier(barriers); + } + + /** + * @brief Set memory barrier by region + * + * Behaves as @ref setMemoryBarrier(), except that the region is + * narrowed around area affected by particular fragment shader, thus + * only the fragment shader-related barries are supported: + * + * - @ref MemoryBarrier::AtomicCounter + * - @ref MemoryBarrier::Framebuffer + * - @ref MemoryBarrier::ShaderImageAccess + * - @ref MemoryBarrier::ShaderStorage + * - @ref MemoryBarrier::TextureFetch + * - @ref MemoryBarrier::Uniform + * + * @see @fn_gl{MemoryBarrierByRegion} + * @requires_gl45 Extension @extension{ARB,ES3_1_compatibility} + * @requires_gles31 Shader load/store is not available in OpenGL ES 3.0 + * and older. + * @requires_gles Shader load/store is not available in WebGL. + */ + void setMemoryBarrierByRegion(MemoryBarriers barriers) { + glMemoryBarrierByRegion(barriers); + } + #endif + + /*@}*/ + + /** @{ @name Renderer management */ + /** * @brief Error status *