diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-08-09 16:05:51 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-08-09 16:05:51 +0000 |
| commit | 86ce0b5436ef7b44563648feab2ddde01a9af784 (patch) | |
| tree | b87c4ee922a65d81d3e3e3965bf5bcf08920ec73 /Graphics/GraphicsEngineOpenGL | |
| parent | Improved incorrect buffer parameters error reporting (diff) | |
| download | DiligentCore-86ce0b5436ef7b44563648feab2ddde01a9af784.tar.gz DiligentCore-86ce0b5436ef7b44563648feab2ddde01a9af784.zip | |
OpenGL backend: added handling of Buffers and RW Buffers
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
6 files changed, 98 insertions, 41 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h index 3753b6b2..0e78be78 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -44,6 +44,7 @@ public: void BindTexture( Int32 Index, GLenum BindTarget, const GLObjectWrappers::GLTextureObj &Tex); void BindSampler( Uint32 Index, const GLObjectWrappers::GLSamplerObj &GLSampler); void BindImage( Uint32 Index, class TextureViewGLImpl *pTexView, GLint MipLevel, GLboolean IsLayered, GLint Layer, GLenum Access, GLenum Format ); + void BindImage( Uint32 Index, class BufferViewGLImpl *pBuffView, GLenum Access, GLenum Format ); void EnsureMemoryBarrier(Uint32 RequiredBarriers, class AsyncWritableResource *pRes = nullptr); void SetPendingMemoryBarriers( Uint32 PendingBarriers ); diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp index 5b23d346..0114db3c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp @@ -338,7 +338,8 @@ void BufferGLImpl::BufferMemoryBarrier( Uint32 RequiredBarriers, GLContextState GL_BUFFER_UPDATE_BARRIER_BIT | GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT | - GL_TEXTURE_FETCH_BARRIER_BIT; + GL_TEXTURE_FETCH_BARRIER_BIT | + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT; VERIFY( (RequiredBarriers & BufferBarriers) !=0, "At least one buffer memory barrier flag should be set" ); VERIFY( (RequiredBarriers & ~BufferBarriers) == 0, "Inappropriate buffer memory barrier flag" ); } diff --git a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp index 8097f9f2..d41cb0ca 100644 --- a/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp @@ -40,7 +40,7 @@ namespace Diligent TBuffViewBase(pRefCounters, pDevice, ViewDesc, pBuffer, bIsDefaultView ), m_GLTexBuffer(false) { - if( ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE && + if( (ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE || ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS) && (pBuffer->GetDesc().Mode == BUFFER_MODE_FORMATTED || pBuffer->GetDesc().Mode == BUFFER_MODE_RAW) ) { #ifdef _MSC_VER diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 55fa5435..0dfff8a5 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -532,13 +532,16 @@ namespace Diligent auto& Resource = Img.pResources[ArrInd]; if (Resource) { - auto* pTexViewOGL = Resource.RawPtr<TextureViewGLImpl>(); - const auto& ViewDesc = pTexViewOGL->GetDesc(); - - if (ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE) + if (Img.ImageType == GL_IMAGE_BUFFER || + Img.ImageType == GL_INT_IMAGE_BUFFER || + Img.ImageType == GL_UNSIGNED_INT_IMAGE_BUFFER) { - auto* pTexGL = pTexViewOGL->GetTexture<TextureBaseGL>(); - pTexGL->TextureMemoryBarrier( + auto* pBuffViewOGL = Resource.RawPtr<BufferViewGLImpl>(); + const auto& ViewDesc = pBuffViewOGL->GetDesc(); + VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS, "Unexpected buffer view type" ); + + auto* pBufferOGL = pBuffViewOGL->GetBuffer<BufferGLImpl>(); + pBufferOGL->BufferMemoryBarrier( GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in // functions issued after the barrier will reflect data written by shaders // prior to the barrier. Additionally, image stores and atomics issued after @@ -546,38 +549,61 @@ namespace Diligent // stores, texture fetches, vertex fetches) initiated prior to the barrier // complete. m_ContextState); - // We cannot set pending memory barriers here, because - // if some texture is bound twice, the logic will fail - m_BoundWritableTextures.push_back( pTexGL ); + m_BoundWritableBuffers.push_back(pBufferOGL); + + auto GlFormat = TypeToGLTexFormat(ViewDesc.Format.ValueType, ViewDesc.Format.NumComponents, ViewDesc.Format.IsNormalized); + m_ContextState.BindImage(Img.BindingPoint + ArrInd, pBuffViewOGL, GL_READ_WRITE, GlFormat); } + else + { + auto* pTexViewOGL = Resource.RawPtr<TextureViewGLImpl>(); + const auto& ViewDesc = pTexViewOGL->GetDesc(); + VERIFY( ViewDesc.ViewType == TEXTURE_VIEW_UNORDERED_ACCESS, "Unexpected buffer view type" ); + + if (ViewDesc.AccessFlags & UAV_ACCESS_FLAG_WRITE) + { + auto* pTexGL = pTexViewOGL->GetTexture<TextureBaseGL>(); + pTexGL->TextureMemoryBarrier( + GL_SHADER_IMAGE_ACCESS_BARRIER_BIT,// Memory accesses using shader image load, store, and atomic built-in + // functions issued after the barrier will reflect data written by shaders + // prior to the barrier. Additionally, image stores and atomics issued after + // the barrier will not execute until all memory accesses (e.g., loads, + // stores, texture fetches, vertex fetches) initiated prior to the barrier + // complete. + m_ContextState); + // We cannot set pending memory barriers here, because + // if some texture is bound twice, the logic will fail + m_BoundWritableTextures.push_back( pTexGL ); + } #ifdef _DEBUG - // Check that the texure being bound has immutable storage - { - m_ContextState.BindTexture(-1, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle()); - GLint IsImmutable = 0; - glGetTexParameteriv( pTexViewOGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); - CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); - VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); - m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), GLObjectWrappers::GLTextureObj(false) ); - } + // Check that the texure being bound has immutable storage + { + m_ContextState.BindTexture(-1, pTexViewOGL->GetBindTarget(), pTexViewOGL->GetHandle()); + GLint IsImmutable = 0; + glGetTexParameteriv( pTexViewOGL->GetBindTarget(), GL_TEXTURE_IMMUTABLE_FORMAT, &IsImmutable ); + CHECK_GL_ERROR( "glGetTexParameteriv() failed" ); + VERIFY( IsImmutable, "Only immutable textures can be bound to pipeline using glBindImageTexture()" ); + m_ContextState.BindTexture( -1, pTexViewOGL->GetBindTarget(), GLObjectWrappers::GLTextureObj(false) ); + } #endif - auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); - // Note that if a format qulifier is specified in the shader, the format - // must match it - - GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; - // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this - // case. If "layered" is FALSE, only the single layer identified by "layer" will - // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. - GLint Layer = ViewDesc.FirstArraySlice; - - auto GLAccess = AccessFlags2GLAccess(ViewDesc.AccessFlags); - // WARNING: Texture being bound to the image unit must be complete - // That means that if an integer texture is being bound, its - // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, - // otherwise it will be incomplete - m_ContextState.BindImage(Img.BindingPoint + ArrInd, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat); + auto GlTexFormat = TexFormatToGLInternalTexFormat( ViewDesc.Format ); + // Note that if a format qulifier is specified in the shader, the format + // must match it + + GLboolean Layered = ViewDesc.NumArraySlices > 1 && ViewDesc.FirstArraySlice == 0; + // If "layered" is TRUE, the entire Mip level is bound. Layer parameter is ignored in this + // case. If "layered" is FALSE, only the single layer identified by "layer" will + // be bound. When "layered" is FALSE, the single bound layer is treated as a 2D texture. + GLint Layer = ViewDesc.FirstArraySlice; + + auto GLAccess = AccessFlags2GLAccess(ViewDesc.AccessFlags); + // WARNING: Texture being bound to the image unit must be complete + // That means that if an integer texture is being bound, its + // GL_TEXTURE_MIN_FILTER and GL_TEXTURE_MAG_FILTER must be NEAREST, + // otherwise it will be incomplete + m_ContextState.BindImage(Img.BindingPoint + ArrInd, pTexViewOGL, ViewDesc.MostDetailedMip, Layered, Layer, GLAccess, GlTexFormat); + } } else { @@ -598,7 +624,7 @@ namespace Diligent { auto* pBufferViewOGL = Resource.RawPtr<BufferViewGLImpl>(); const auto& ViewDesc = pBufferViewOGL->GetDesc(); - VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS || ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpceted buffer view type" ); + VERIFY( ViewDesc.ViewType == BUFFER_VIEW_UNORDERED_ACCESS || ViewDesc.ViewType == BUFFER_VIEW_SHADER_RESOURCE, "Unexpected buffer view type" ); auto* pBufferOGL = pBufferViewOGL->GetBuffer<BufferGLImpl>(); pBufferOGL->BufferMemoryBarrier( diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index 246f1806..e49be10e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -261,6 +261,31 @@ namespace Diligent #endif } + void GLContextState::BindImage( Uint32 Index, BufferViewGLImpl* pBuffView, GLenum Access, GLenum Format ) + { +#if GL_ARB_shader_image_load_store + BoundImageInfo NewImageInfo( + pBuffView->GetUniqueID(), + 0, + GL_FALSE, + 0, + Access, + Format + ); + if( Index >= m_BoundImages.size() ) + m_BoundImages.resize( Index + 1 ); + if( !(m_BoundImages[Index] == NewImageInfo) ) + { + m_BoundImages[Index] = NewImageInfo; + GLint GLBuffHandle = pBuffView->GetTexBufferHandle(); + glBindImageTexture( Index, GLBuffHandle, 0, GL_FALSE, 0, Access, Format ); + CHECK_GL_ERROR( "glBindImageTexture() failed" ); + } +#else + UNSUPPORTED("GL_ARB_shader_image_load_store is not supported"); +#endif + } + void GLContextState::EnsureMemoryBarrier( Uint32 RequiredBarriers, AsyncWritableResource *pRes/* = nullptr */ ) { #if GL_ARB_shader_image_load_store diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp index 00f07ea0..1ad1b73c 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp @@ -415,9 +415,9 @@ namespace Diligent // glGetProgramResourceLocation( program, GL_UNIFORM, name ); // The latter is only available in GL 4.4 and GLES 3.1 - auto ResourceType = dataType == GL_SAMPLER_BUFFER || - dataType == GL_INT_SAMPLER_BUFFER || - dataType == GL_UNSIGNED_INT_SAMPLER_BUFFER ? + const auto ResourceType = dataType == GL_SAMPLER_BUFFER || + dataType == GL_INT_SAMPLER_BUFFER || + dataType == GL_UNSIGNED_INT_SAMPLER_BUFFER ? SHADER_RESOURCE_TYPE_BUFFER_SRV : SHADER_RESOURCE_TYPE_TEXTURE_SRV; RemoveArrayBrackets(Name.data()); @@ -482,11 +482,15 @@ namespace Diligent RemoveArrayBrackets(Name.data()); + const auto ResourceType = dataType == GL_IMAGE_BUFFER || + dataType == GL_INT_IMAGE_BUFFER || + dataType == GL_UNSIGNED_INT_IMAGE_BUFFER ? + SHADER_RESOURCE_TYPE_BUFFER_UAV : SHADER_RESOURCE_TYPE_TEXTURE_UAV; Images.emplace_back( Owner, NamesPool.emplace(Name.data()).first->c_str(), SHADER_RESOURCE_VARIABLE_TYPE_STATIC, - SHADER_RESOURCE_TYPE_TEXTURE_UAV, + ResourceType, Uint16{0xFFFF}, // Variable index is assigned by AllocateResources static_cast<Uint32>(size), nullptr, // pResources |
