Renderer/CommandBuffer: Add support for texture blit/copy
This commit is contained in:
@@ -78,6 +78,10 @@ namespace Nz
|
||||
if (context->glPushDebugGroup)
|
||||
context->glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, GLsizei(command.regionName.size()), command.regionName.data());
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, BlitTextureData>)
|
||||
{
|
||||
context->BlitTexture(*command.source, *command.target, command.sourceBox, command.targetBox, command.filter);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, CopyBufferData>)
|
||||
{
|
||||
context->BindBuffer(GL::BufferTarget::CopyRead, command.source);
|
||||
@@ -89,6 +93,10 @@ namespace Nz
|
||||
context->BindBuffer(GL::BufferTarget::CopyWrite, command.target);
|
||||
context->glBufferSubData(GL_COPY_WRITE_BUFFER, command.targetOffset, command.size, command.memory);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, CopyTextureData>)
|
||||
{
|
||||
context->CopyTexture(*command.source, *command.target, command.sourceBox, command.targetPoint);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, DrawData>)
|
||||
{
|
||||
ApplyStates(*context, command.states);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipeline.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLRenderPipelineLayout.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLShaderBinding.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLTexture.hpp>
|
||||
#include <Nazara/OpenGLRenderer/OpenGLUploadPool.hpp>
|
||||
#include <Nazara/OpenGLRenderer/Debug.hpp>
|
||||
|
||||
@@ -60,6 +61,14 @@ namespace Nz
|
||||
m_commandBuffer.BindVertexBuffer(binding, glBuffer.GetBuffer().GetObjectId(), offset);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout /*fromLayout*/, const Texture& toTexture, const Boxui& toBox, TextureLayout /*toLayout*/, SamplerFilter filter)
|
||||
{
|
||||
const OpenGLTexture& sourceTexture = static_cast<const OpenGLTexture&>(fromTexture);
|
||||
const OpenGLTexture& targetTexture = static_cast<const OpenGLTexture&>(toTexture);
|
||||
|
||||
m_commandBuffer.BlitTexture(sourceTexture.GetTexture(), fromBox, targetTexture.GetTexture(), toBox, filter);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
||||
{
|
||||
OpenGLBuffer& sourceBuffer = *static_cast<OpenGLBuffer*>(source.GetBuffer());
|
||||
@@ -75,6 +84,14 @@ namespace Nz
|
||||
m_commandBuffer.CopyBuffer(allocation, targetBuffer.GetBuffer().GetObjectId(), size, sourceOffset, target.GetOffset() + targetOffset);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::CopyTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Vector3ui& toPos, TextureLayout toLayout)
|
||||
{
|
||||
const OpenGLTexture& sourceTexture = static_cast<const OpenGLTexture&>(fromTexture);
|
||||
const OpenGLTexture& targetTexture = static_cast<const OpenGLTexture&>(toTexture);
|
||||
|
||||
m_commandBuffer.CopyTexture(sourceTexture.GetTexture(), fromBox, targetTexture.GetTexture(), toPos);
|
||||
}
|
||||
|
||||
void OpenGLCommandBufferBuilder::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||
{
|
||||
m_commandBuffer.Draw(vertexCount, instanceCount, firstVertex, firstInstance);
|
||||
|
||||
@@ -249,7 +249,7 @@ namespace Nz::GL
|
||||
}
|
||||
}
|
||||
|
||||
bool Context::BlitTexture(const Texture& source, const Texture& destination, const Boxui& srcBox, const Vector3ui& dstPos, SamplerFilter filter) const
|
||||
bool Context::BlitTexture(const Texture& source, const Texture& destination, const Boxui& srcBox, const Boxui& dstBox, SamplerFilter filter) const
|
||||
{
|
||||
if (!m_blitFramebuffers && !InitializeBlitFramebuffers())
|
||||
return false;
|
||||
@@ -277,7 +277,7 @@ namespace Nz::GL
|
||||
return false;
|
||||
}
|
||||
|
||||
glBlitFramebuffer(srcBox.x, srcBox.y, srcBox.x + srcBox.width, srcBox.y + srcBox.height, dstPos.x, dstPos.y, dstPos.x + srcBox.width, dstPos.y + srcBox.height, GL_COLOR_BUFFER_BIT, ToOpenGL(filter));
|
||||
glBlitFramebuffer(srcBox.x, srcBox.y, srcBox.x + srcBox.width, srcBox.y + srcBox.height, dstBox.x, dstBox.y, dstBox.x + dstBox.width, dstBox.y + srcBox.height, GL_COLOR_BUFFER_BIT, ToOpenGL(filter));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace Nz::GL
|
||||
bool Context::CopyTexture(const Texture& source, const Texture& destination, const Boxui& srcBox, const Vector3ui& dstPos) const
|
||||
{
|
||||
// Use glCopyImageSubData if available
|
||||
if (glCopyImageSubData && false)
|
||||
if (glCopyImageSubData)
|
||||
{
|
||||
GLuint srcImage = source.GetObjectId();
|
||||
GLenum srcTarget = ToOpenGL(source.GetTarget());
|
||||
@@ -310,7 +310,7 @@ namespace Nz::GL
|
||||
else
|
||||
{
|
||||
// If glCopyImageSubData is not available, fallback to framebuffer blit
|
||||
return BlitTexture(source, destination, srcBox, dstPos, SamplerFilter::Nearest);
|
||||
return BlitTexture(source, destination, srcBox, Boxui(dstPos.x, dstPos.y, dstPos.z, srcBox.width, srcBox.height, srcBox.depth), SamplerFilter::Nearest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,6 +110,50 @@ namespace Nz
|
||||
m_commandBuffer.BindVertexBuffer(binding, vkBuffer.GetBuffer(), offset);
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::BlitTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Boxui& toBox, TextureLayout toLayout, SamplerFilter filter)
|
||||
{
|
||||
const VulkanTexture& vkFromTexture = static_cast<const VulkanTexture&>(fromTexture);
|
||||
const VulkanTexture& vkToTexture = static_cast<const VulkanTexture&>(toTexture);
|
||||
|
||||
VkImageSubresourceLayers todo = {
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
1,
|
||||
0,
|
||||
1
|
||||
};
|
||||
|
||||
VkImageBlit region = {
|
||||
todo,
|
||||
{
|
||||
{
|
||||
SafeCast<Int32>(fromBox.x),
|
||||
SafeCast<Int32>(fromBox.y),
|
||||
SafeCast<Int32>(fromBox.z)
|
||||
},
|
||||
{
|
||||
SafeCast<Int32>(fromBox.x + fromBox.width),
|
||||
SafeCast<Int32>(fromBox.y + fromBox.height),
|
||||
SafeCast<Int32>(fromBox.z + fromBox.depth)
|
||||
}
|
||||
},
|
||||
todo,
|
||||
{
|
||||
{
|
||||
SafeCast<Int32>(toBox.x),
|
||||
SafeCast<Int32>(toBox.y),
|
||||
SafeCast<Int32>(toBox.z)
|
||||
},
|
||||
{
|
||||
SafeCast<Int32>(toBox.x + toBox.width),
|
||||
SafeCast<Int32>(toBox.y + toBox.height),
|
||||
SafeCast<Int32>(toBox.z + toBox.depth)
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
m_commandBuffer.BlitImage(vkFromTexture.GetImage(), ToVulkan(fromLayout), vkToTexture.GetImage(), ToVulkan(toLayout), region, ToVulkan(filter));
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::CopyBuffer(const RenderBufferView& source, const RenderBufferView& target, UInt64 size, UInt64 sourceOffset, UInt64 targetOffset)
|
||||
{
|
||||
VulkanBuffer& sourceBuffer = *static_cast<VulkanBuffer*>(source.GetBuffer());
|
||||
@@ -126,6 +170,40 @@ namespace Nz
|
||||
m_commandBuffer.CopyBuffer(vkAllocation.buffer, targetBuffer.GetBuffer(), size, vkAllocation.offset + sourceOffset, target.GetOffset() + targetOffset);
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::CopyTexture(const Texture& fromTexture, const Boxui& fromBox, TextureLayout fromLayout, const Texture& toTexture, const Vector3ui& toPos, TextureLayout toLayout)
|
||||
{
|
||||
const VulkanTexture& vkFromTexture = static_cast<const VulkanTexture&>(fromTexture);
|
||||
const VulkanTexture& vkToTexture = static_cast<const VulkanTexture&>(toTexture);
|
||||
|
||||
VkImageSubresourceLayers todo = {
|
||||
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
1,
|
||||
0,
|
||||
1
|
||||
};
|
||||
|
||||
VkImageCopy region = {
|
||||
todo,
|
||||
{
|
||||
SafeCast<Int32>(fromBox.x),
|
||||
SafeCast<Int32>(fromBox.y),
|
||||
SafeCast<Int32>(fromBox.z)
|
||||
},
|
||||
{
|
||||
SafeCast<Int32>(toPos.x),
|
||||
SafeCast<Int32>(toPos.y),
|
||||
SafeCast<Int32>(toPos.z),
|
||||
},
|
||||
{
|
||||
SafeCast<Int32>(fromBox.width),
|
||||
SafeCast<Int32>(fromBox.height),
|
||||
SafeCast<Int32>(fromBox.depth)
|
||||
}
|
||||
};
|
||||
|
||||
m_commandBuffer.CopyImage(vkFromTexture.GetImage(), ToVulkan(fromLayout), vkToTexture.GetImage(), ToVulkan(toLayout), region);
|
||||
}
|
||||
|
||||
void VulkanCommandBufferBuilder::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||
{
|
||||
m_commandBuffer.Draw(vertexCount, instanceCount, firstVertex, firstInstance);
|
||||
|
||||
Reference in New Issue
Block a user