Renderer: Working compute implementation

This commit is contained in:
SirLynix
2022-12-25 16:08:35 +01:00
committed by Jérôme Leclercq
parent 4605eed0da
commit fe8715f1fb
31 changed files with 615 additions and 167 deletions

View File

@@ -100,11 +100,13 @@ namespace Nz
throw std::runtime_error("compute shaders are not supported on this device");
command.states.pipeline->Apply(*context);
ApplyBindings(*context, command.bindings);
context->glDispatchCompute(command.numGroupsX, command.numGroupsY, command.numGroupsZ);
}
else if constexpr (std::is_same_v<T, DrawData>)
{
ApplyStates(*context, command.states);
ApplyBindings(*context, command.bindings);
context->glDrawArraysInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.firstVertex, command.vertexCount, command.instanceCount);
}
else if constexpr (std::is_same_v<T, DrawIndexedData>)
@@ -120,6 +122,7 @@ namespace Nz
}
ApplyStates(*context, command.states);
ApplyBindings(*context, command.bindings);
context->glDrawElementsInstanced(ToOpenGL(command.states.pipeline->GetPipelineInfo().primitiveMode), command.indexCount, ToOpenGL(command.states.indexBufferType), origin, command.instanceCount);
}
else if constexpr (std::is_same_v<T, EndDebugRegionData>)
@@ -127,6 +130,11 @@ namespace Nz
if (context->glPopDebugGroup)
context->glPopDebugGroup();
}
else if constexpr (std::is_same_v<T, MemoryBarrier>)
{
if (context->glMemoryBarrier)
context->glMemoryBarrier(command.barriers);
}
else if constexpr (std::is_same_v<T, SetFrameBufferData>)
{
command.framebuffer->Activate();
@@ -329,10 +337,8 @@ namespace Nz
// No OpenGL object to name
}
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
void OpenGLCommandBuffer::ApplyBindings(const GL::Context& context, const ShaderBindings& states)
{
states.pipeline->Apply(context, states.shouldFlipY);
unsigned int setIndex = 0;
for (const auto& [pipelineLayout, shaderBinding] : states.shaderBindings)
{
@@ -343,6 +349,11 @@ namespace Nz
setIndex++;
}
}
void OpenGLCommandBuffer::ApplyStates(const GL::Context& context, const DrawStates& states)
{
states.pipeline->Apply(context, states.shouldFlipY);
if (states.scissorRegion)
context.SetScissorBox(states.scissorRegion->x, states.scissorRegion->y, states.scissorRegion->width, states.scissorRegion->height);

View File

@@ -34,6 +34,21 @@ namespace Nz
m_commandBuffer.BindComputePipeline(&glPipeline);
}
void OpenGLCommandBufferBuilder::BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding)
{
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
m_commandBuffer.BindComputeShaderBinding(glBinding.GetOwner(), set, &glBinding);
}
void OpenGLCommandBufferBuilder::BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
{
const OpenGLRenderPipelineLayout& glPipelineLayout = static_cast<const OpenGLRenderPipelineLayout&>(pipelineLayout);
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
m_commandBuffer.BindComputeShaderBinding(glPipelineLayout, set, &glBinding);
}
void OpenGLCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
{
const OpenGLBuffer& glBuffer = static_cast<const OpenGLBuffer&>(indexBuffer);
@@ -48,19 +63,19 @@ namespace Nz
m_commandBuffer.BindRenderPipeline(&glPipeline);
}
void OpenGLCommandBufferBuilder::BindShaderBinding(UInt32 set, const ShaderBinding& binding)
void OpenGLCommandBufferBuilder::BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding)
{
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
m_commandBuffer.BindShaderBinding(glBinding.GetOwner(), set, &glBinding);
m_commandBuffer.BindRenderShaderBinding(glBinding.GetOwner(), set, &glBinding);
}
void OpenGLCommandBufferBuilder::BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
void OpenGLCommandBufferBuilder::BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
{
const OpenGLRenderPipelineLayout& glPipelineLayout = static_cast<const OpenGLRenderPipelineLayout&>(pipelineLayout);
const OpenGLShaderBinding& glBinding = static_cast<const OpenGLShaderBinding&>(binding);
m_commandBuffer.BindShaderBinding(glPipelineLayout, set, &glBinding);
m_commandBuffer.BindRenderShaderBinding(glPipelineLayout, set, &glBinding);
}
void OpenGLCommandBufferBuilder::BindVertexBuffer(UInt32 binding, const RenderBuffer& vertexBuffer, UInt64 offset)
@@ -151,8 +166,23 @@ namespace Nz
m_commandBuffer.SetViewport(viewportRegion);
}
void OpenGLCommandBufferBuilder::TextureBarrier(PipelineStageFlags /*srcStageMask*/, PipelineStageFlags /*dstStageMask*/, MemoryAccessFlags /*srcAccessMask*/, MemoryAccessFlags /*dstAccessMask*/, TextureLayout /*oldLayout*/, TextureLayout /*newLayout*/, const Texture& /*texture*/)
void OpenGLCommandBufferBuilder::TextureBarrier(PipelineStageFlags /*srcStageMask*/, PipelineStageFlags /*dstStageMask*/, MemoryAccessFlags srcAccessMask, MemoryAccessFlags dstAccessMask, TextureLayout /*oldLayout*/, TextureLayout /*newLayout*/, const Texture& /*texture*/)
{
/* nothing to do */
if (srcAccessMask.Test(MemoryAccess::ShaderWrite))
{
GLbitfield barriers = 0;
if (dstAccessMask.Test(MemoryAccess::ColorRead))
barriers |= GL_TEXTURE_FETCH_BARRIER_BIT;
if (dstAccessMask.Test(MemoryAccess::ShaderRead))
barriers |= GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
if (dstAccessMask.Test(MemoryAccess::ShaderWrite))
barriers |= GL_SHADER_IMAGE_ACCESS_BARRIER_BIT;
if (barriers != 0)
m_commandBuffer.InsertMemoryBarrier(barriers);
}
}
}

View File

@@ -77,8 +77,7 @@ namespace Nz
if (m_referenceContext->IsExtensionSupported(GL::Extension::ShaderImageLoadStore))
{
m_deviceInfo.features.textureRead = true;
m_deviceInfo.features.textureWrite = true;
m_deviceInfo.features.textureReadWrite = true;
m_deviceInfo.features.textureWriteWithoutFormat = true;
}

View File

@@ -117,26 +117,22 @@ namespace Nz
auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, binding.bindingIndex);
if (const OpenGLTexture* glTexture = static_cast<const OpenGLTexture*>(arg.texture))
{
const TextureViewInfo& viewInfo = glTexture->GetTextureViewInfo();
std::optional<GLTextureFormat> format = DescribeTextureFormat(viewInfo.reinterpretFormat);
std::optional<GLTextureFormat> format = DescribeTextureFormat(glTexture->GetFormat());
if (!format)
throw std::runtime_error("unexpected texture format");
textureDescriptor.access = ToOpenGL(arg.access);
textureDescriptor.format = format->internalFormat;
if (viewInfo.layerCount > 1)
{
textureDescriptor.layered = true;
textureDescriptor.layer = 0;
}
else
{
textureDescriptor.layered = false;
textureDescriptor.layer = viewInfo.baseArrayLayer;
}
textureDescriptor.level = viewInfo.baseMipLevel;
// Don't bother emulating texture views as their support is virtually guaranteed when compute shaders are available
if (Nz::ImageType imageType = glTexture->GetType(); imageType == ImageType::Cubemap || imageType == ImageType::E1D_Array || imageType == ImageType::E2D_Array)
textureDescriptor.layered = true;
else
textureDescriptor.layered = false;
textureDescriptor.level = 0;
textureDescriptor.layer = 0;
textureDescriptor.texture = glTexture->GetTexture().GetObjectId();
}
else

View File

@@ -117,31 +117,6 @@ namespace Nz
return std::make_shared<OpenGLTexture>(std::static_pointer_cast<OpenGLTexture>(shared_from_this()), viewInfo);
}
PixelFormat OpenGLTexture::GetFormat() const
{
return m_textureInfo.pixelFormat;
}
UInt8 OpenGLTexture::GetLevelCount() const
{
return m_textureInfo.levelCount;
}
OpenGLTexture* OpenGLTexture::GetParentTexture() const
{
return m_parentTexture.get();
}
Vector3ui OpenGLTexture::GetSize(UInt8 level) const
{
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
}
ImageType OpenGLTexture::GetType() const
{
return m_textureInfo.type;
}
bool OpenGLTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
{
auto format = DescribeTextureFormat(m_textureInfo.pixelFormat);

View File

@@ -633,6 +633,13 @@ namespace Nz::GL
assert(maxUniformBufferUnits > 0);
m_state.uboUnits.resize(maxUniformBufferUnits);
if (IsExtensionSupported(Extension::ShaderImageLoadStore))
{
unsigned int maxImageUnits = GetInteger<unsigned int>(GL_MAX_IMAGE_UNITS);
assert(maxImageUnits > 0);
m_state.imageUnits.resize(maxImageUnits);
}
if (IsExtensionSupported(Extension::StorageBuffers))
{
unsigned int maxStorageBufferUnits = GetInteger<unsigned int>(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);