Renderer: Working compute implementation
This commit is contained in:
committed by
Jérôme Leclercq
parent
4605eed0da
commit
fe8715f1fb
@@ -458,7 +458,7 @@ namespace Nz
|
||||
builder.SetViewport(renderRegion);
|
||||
builder.BindRenderPipeline(*graphics->GetBlitPipeline(false));
|
||||
|
||||
builder.BindShaderBinding(0, *data.blitShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *data.blitShaderBinding);
|
||||
builder.Draw(3);
|
||||
}
|
||||
builder.EndDebugRegion();
|
||||
@@ -652,7 +652,7 @@ namespace Nz
|
||||
{
|
||||
const ShaderBindingPtr& blitShaderBinding = viewerData->blitShaderBinding;
|
||||
|
||||
builder.BindShaderBinding(0, *blitShaderBinding);
|
||||
builder.BindRenderShaderBinding(0, *blitShaderBinding);
|
||||
builder.Draw(3);
|
||||
|
||||
if (first)
|
||||
|
||||
@@ -112,9 +112,8 @@ namespace Nz
|
||||
enabledFeatures.depthClamping = !config.forceDisableFeatures.depthClamping && renderDeviceInfo[bestRenderDeviceIndex].features.depthClamping;
|
||||
enabledFeatures.nonSolidFaceFilling = !config.forceDisableFeatures.nonSolidFaceFilling && renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling;
|
||||
enabledFeatures.storageBuffers = !config.forceDisableFeatures.storageBuffers && renderDeviceInfo[bestRenderDeviceIndex].features.storageBuffers;
|
||||
enabledFeatures.textureRead = !config.forceDisableFeatures.textureRead && renderDeviceInfo[bestRenderDeviceIndex].features.textureRead;
|
||||
enabledFeatures.textureReadWithoutFormat = !config.forceDisableFeatures.textureReadWithoutFormat && renderDeviceInfo[bestRenderDeviceIndex].features.textureReadWithoutFormat;
|
||||
enabledFeatures.textureWrite = !config.forceDisableFeatures.textureWrite && renderDeviceInfo[bestRenderDeviceIndex].features.textureWrite;
|
||||
enabledFeatures.textureReadWrite = !config.forceDisableFeatures.textureReadWrite && renderDeviceInfo[bestRenderDeviceIndex].features.textureReadWrite;
|
||||
enabledFeatures.textureWriteWithoutFormat = !config.forceDisableFeatures.textureWriteWithoutFormat && renderDeviceInfo[bestRenderDeviceIndex].features.textureWriteWithoutFormat;
|
||||
enabledFeatures.unrestrictedTextureViews = !config.forceDisableFeatures.unrestrictedTextureViews && renderDeviceInfo[bestRenderDeviceIndex].features.unrestrictedTextureViews;
|
||||
|
||||
|
||||
@@ -316,7 +316,7 @@ namespace Nz
|
||||
|
||||
if (currentShaderBinding != drawData.shaderBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding);
|
||||
commandBuffer.BindRenderShaderBinding(0, *drawData.shaderBinding);
|
||||
currentShaderBinding = drawData.shaderBinding;
|
||||
}
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace Nz
|
||||
|
||||
if (currentShaderBinding != drawData.shaderBinding)
|
||||
{
|
||||
commandBuffer.BindShaderBinding(0, *drawData.shaderBinding);
|
||||
commandBuffer.BindRenderShaderBinding(0, *drawData.shaderBinding);
|
||||
currentShaderBinding = drawData.shaderBinding;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace Nz
|
||||
if (m_drawCalls.empty())
|
||||
return;
|
||||
|
||||
builder.BindShaderBinding(0, *m_currentViewerData.binding);
|
||||
builder.BindRenderShaderBinding(0, *m_currentViewerData.binding);
|
||||
builder.BindRenderPipeline(*m_renderPipeline);
|
||||
|
||||
for (auto& drawCall : m_drawCalls)
|
||||
|
||||
@@ -46,9 +46,8 @@ namespace Nz
|
||||
NzValidateFeature(depthClamping, "depth clamping feature")
|
||||
NzValidateFeature(nonSolidFaceFilling, "non-solid face filling feature")
|
||||
NzValidateFeature(storageBuffers, "storage buffers support")
|
||||
NzValidateFeature(textureRead, "texture read")
|
||||
NzValidateFeature(textureReadWithoutFormat, "texture read without format")
|
||||
NzValidateFeature(textureWrite, "texture write")
|
||||
NzValidateFeature(textureReadWrite, "texture read/write")
|
||||
NzValidateFeature(textureWriteWithoutFormat, "texture write without format")
|
||||
NzValidateFeature(unrestrictedTextureViews, "unrestricted texture view support")
|
||||
|
||||
|
||||
@@ -58,9 +58,8 @@ namespace Nz
|
||||
deviceInfo.features.depthClamping = physDevice.features.depthClamp;
|
||||
deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid;
|
||||
deviceInfo.features.storageBuffers = true;
|
||||
deviceInfo.features.textureRead = true;
|
||||
deviceInfo.features.textureReadWithoutFormat = physDevice.features.shaderStorageImageReadWithoutFormat;
|
||||
deviceInfo.features.textureWrite = true;
|
||||
deviceInfo.features.textureReadWrite = true;
|
||||
deviceInfo.features.textureWriteWithoutFormat = physDevice.features.shaderStorageImageWriteWithoutFormat;
|
||||
deviceInfo.features.unrestrictedTextureViews = true;
|
||||
|
||||
|
||||
@@ -80,6 +80,22 @@ namespace Nz
|
||||
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vkPipeline.GetPipeline());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindComputeShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
const VulkanRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
|
||||
|
||||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_COMPUTE, pipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindComputeShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanRenderPipelineLayout& vkPipelineLayout = static_cast<const VulkanRenderPipelineLayout&>(pipelineLayout);
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
|
||||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_COMPUTE, vkPipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindIndexBuffer(const RenderBuffer& indexBuffer, IndexType indexType, UInt64 offset)
|
||||
{
|
||||
const VulkanBuffer& vkBuffer = static_cast<const VulkanBuffer&>(indexBuffer);
|
||||
@@ -97,7 +113,7 @@ namespace Nz
|
||||
m_commandBuffer.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, vkPipeline.Get(*m_currentRenderPass, m_currentSubpassIndex));
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
void VulkanCommandBufferBuilder::BindRenderShaderBinding(UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
const VulkanRenderPipelineLayout& pipelineLayout = vkBinding.GetOwner();
|
||||
@@ -105,7 +121,7 @@ namespace Nz
|
||||
m_commandBuffer.BindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.GetPipelineLayout(), set, vkBinding.GetDescriptorSet());
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BindShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
void VulkanCommandBufferBuilder::BindRenderShaderBinding(const RenderPipelineLayout& pipelineLayout, UInt32 set, const ShaderBinding& binding)
|
||||
{
|
||||
const VulkanRenderPipelineLayout& vkPipelineLayout = static_cast<const VulkanRenderPipelineLayout&>(pipelineLayout);
|
||||
const VulkanShaderBinding& vkBinding = static_cast<const VulkanShaderBinding&>(binding);
|
||||
|
||||
@@ -294,31 +294,6 @@ namespace Nz
|
||||
return std::make_shared<VulkanTexture>(std::static_pointer_cast<VulkanTexture>(shared_from_this()), viewInfo);
|
||||
}
|
||||
|
||||
PixelFormat VulkanTexture::GetFormat() const
|
||||
{
|
||||
return m_textureInfo.pixelFormat;
|
||||
}
|
||||
|
||||
UInt8 VulkanTexture::GetLevelCount() const
|
||||
{
|
||||
return m_textureInfo.levelCount;
|
||||
}
|
||||
|
||||
VulkanTexture* VulkanTexture::GetParentTexture() const
|
||||
{
|
||||
return m_parentTexture.get();
|
||||
}
|
||||
|
||||
Vector3ui VulkanTexture::GetSize(UInt8 level) const
|
||||
{
|
||||
return Vector3ui(GetLevelSize(m_textureInfo.width, level), GetLevelSize(m_textureInfo.height, level), GetLevelSize(m_textureInfo.depth, level));
|
||||
}
|
||||
|
||||
ImageType VulkanTexture::GetType() const
|
||||
{
|
||||
return m_textureInfo.type;
|
||||
}
|
||||
|
||||
bool VulkanTexture::Update(const void* ptr, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level)
|
||||
{
|
||||
std::size_t textureSize = box.width * box.height * box.depth * PixelFormatInfo::GetBytesPerPixel(m_textureInfo.pixelFormat);
|
||||
|
||||
Reference in New Issue
Block a user