summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineOpenGL
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-08-09 16:05:51 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-08-09 16:05:51 +0000
commit86ce0b5436ef7b44563648feab2ddde01a9af784 (patch)
treeb87c4ee922a65d81d3e3e3965bf5bcf08920ec73 /Graphics/GraphicsEngineOpenGL
parentImproved incorrect buffer parameters error reporting (diff)
downloadDiligentCore-86ce0b5436ef7b44563648feab2ddde01a9af784.tar.gz
DiligentCore-86ce0b5436ef7b44563648feab2ddde01a9af784.zip
OpenGL backend: added handling of Buffers and RW Buffers
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/GLContextState.h1
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/BufferGLImpl.cpp3
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/BufferViewGLImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp96
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp25
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp12
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