Renderer/Texture: Add Copy method (wip)
This commit is contained in:
parent
72f2a5b531
commit
db85372778
|
|
@ -23,6 +23,8 @@ namespace Nz
|
||||||
OpenGLTexture(OpenGLTexture&&) = delete;
|
OpenGLTexture(OpenGLTexture&&) = delete;
|
||||||
~OpenGLTexture() = default;
|
~OpenGLTexture() = default;
|
||||||
|
|
||||||
|
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||||
|
|
||||||
PixelFormat GetFormat() const override;
|
PixelFormat GetFormat() const override;
|
||||||
UInt8 GetLevelCount() const override;
|
UInt8 GetLevelCount() const override;
|
||||||
Vector3ui GetSize(UInt8 level = 0) const override;
|
Vector3ui GetSize(UInt8 level = 0) const override;
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,8 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERARBPROC) (GLuint shader, const G
|
||||||
cb(glVertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC) \
|
cb(glVertexAttribPointer, PFNGLVERTEXATTRIBPOINTERPROC) \
|
||||||
cb(glViewport, PFNGLVIEWPORTPROC) \
|
cb(glViewport, PFNGLVIEWPORTPROC) \
|
||||||
\
|
\
|
||||||
|
extCb(glCopyImageSubData, PFNGLCOPYIMAGESUBDATAPROC) \
|
||||||
|
\
|
||||||
extCb(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \
|
extCb(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \
|
||||||
\
|
\
|
||||||
extCb(glPolygonMode, PFNGLPOLYGONMODEPROC) \
|
extCb(glPolygonMode, PFNGLPOLYGONMODEPROC) \
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,8 @@ namespace Nz
|
||||||
Texture(Texture&&) = delete;
|
Texture(Texture&&) = delete;
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
|
virtual bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos = Vector3ui::Zero()) = 0;
|
||||||
|
|
||||||
virtual PixelFormat GetFormat() const = 0;
|
virtual PixelFormat GetFormat() const = 0;
|
||||||
virtual UInt8 GetLevelCount() const = 0;
|
virtual UInt8 GetLevelCount() const = 0;
|
||||||
virtual Vector3ui GetSize(UInt8 level = 0) const = 0;
|
virtual Vector3ui GetSize(UInt8 level = 0) const = 0;
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@ namespace Nz
|
||||||
VulkanTexture(VulkanTexture&&) = delete;
|
VulkanTexture(VulkanTexture&&) = delete;
|
||||||
~VulkanTexture();
|
~VulkanTexture();
|
||||||
|
|
||||||
|
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||||
|
|
||||||
PixelFormat GetFormat() const override;
|
PixelFormat GetFormat() const override;
|
||||||
inline VkImage GetImage() const;
|
inline VkImage GetImage() const;
|
||||||
inline VkImageView GetImageView() const;
|
inline VkImageView GetImageView() const;
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,8 @@ namespace Nz
|
||||||
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, const VkImageSubresourceLayers& subresourceLayers, UInt32 width, UInt32 height, UInt32 depth = 1);
|
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, const VkImageSubresourceLayers& subresourceLayers, UInt32 width, UInt32 height, UInt32 depth = 1);
|
||||||
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, const VkImageSubresourceLayers& subresourceLayers, const VkBufferImageCopy& region);
|
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, const VkImageSubresourceLayers& subresourceLayers, const VkBufferImageCopy& region);
|
||||||
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, const VkImageSubresourceLayers& subresourceLayers, UInt32 regionCount, const VkBufferImageCopy* regions);
|
inline void CopyBufferToImage(VkBuffer source, VkImage target, VkImageLayout targetLayout, const VkImageSubresourceLayers& subresourceLayers, UInt32 regionCount, const VkBufferImageCopy* regions);
|
||||||
|
inline void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, const VkImageCopy& region);
|
||||||
|
inline void CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, UInt32 regionCount, const VkImageCopy* regions);
|
||||||
|
|
||||||
inline void Draw(UInt32 vertexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0);
|
inline void Draw(UInt32 vertexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, UInt32 firstInstance = 0);
|
||||||
inline void DrawIndexed(UInt32 indexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, Int32 vertexOffset = 0, UInt32 firstInstance = 0);
|
inline void DrawIndexed(UInt32 indexCount, UInt32 instanceCount = 1, UInt32 firstVertex = 0, Int32 vertexOffset = 0, UInt32 firstInstance = 0);
|
||||||
|
|
|
||||||
|
|
@ -282,6 +282,16 @@ namespace Nz
|
||||||
return m_pool->GetDevice()->vkCmdCopyBufferToImage(m_handle, source, target, targetLayout, regionCount, regions);
|
return m_pool->GetDevice()->vkCmdCopyBufferToImage(m_handle, source, target, targetLayout, regionCount, regions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void CommandBuffer::CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, const VkImageCopy& region)
|
||||||
|
{
|
||||||
|
return CopyImage(srcImage, srcImageLayout, dstImage, dstImageLayout, 1U, ®ion);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CommandBuffer::CopyImage(VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, UInt32 regionCount, const VkImageCopy* regions)
|
||||||
|
{
|
||||||
|
return m_pool->GetDevice()->vkCmdCopyImage(m_handle, srcImage, srcImageLayout, dstImage, dstImageLayout, regionCount, regions);
|
||||||
|
}
|
||||||
|
|
||||||
inline void CommandBuffer::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
inline void CommandBuffer::Draw(UInt32 vertexCount, UInt32 instanceCount, UInt32 firstVertex, UInt32 firstInstance)
|
||||||
{
|
{
|
||||||
return m_pool->GetDevice()->vkCmdDraw(m_handle, vertexCount, instanceCount, firstVertex, firstInstance);
|
return m_pool->GetDevice()->vkCmdDraw(m_handle, vertexCount, instanceCount, firstVertex, firstInstance);
|
||||||
|
|
|
||||||
|
|
@ -48,23 +48,14 @@ namespace Nz
|
||||||
|
|
||||||
if (oldImage)
|
if (oldImage)
|
||||||
{
|
{
|
||||||
return nullptr;
|
const Texture& oldTexture = static_cast<const Texture&>(*oldImage);
|
||||||
/*const Texture& oldTexture = static_cast<const Texture&>(*oldImage);
|
Vector3ui oldSize = oldTexture.GetSize();
|
||||||
|
|
||||||
// Copy of old data
|
if (!newTexture->Copy(oldTexture, Rectui(0, 0, oldSize.x, oldSize.y)))
|
||||||
///TODO: Copy from texture to texture
|
|
||||||
Image image;
|
|
||||||
if (!oldTexture->Download(&image))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to download old texture");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!newTexture->Update(&image, Rectui(0, 0, image.GetWidth(), image.GetHeight())))
|
|
||||||
{
|
{
|
||||||
NazaraError("Failed to update texture");
|
NazaraError("Failed to update texture");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return newTexture;
|
return newTexture;
|
||||||
|
|
|
||||||
|
|
@ -53,6 +53,32 @@ namespace Nz
|
||||||
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_A, format->swizzleA);
|
m_texture.SetParameteri(GL_TEXTURE_SWIZZLE_A, format->swizzleA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OpenGLTexture::Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos)
|
||||||
|
{
|
||||||
|
const OpenGLTexture& glTexture = static_cast<const OpenGLTexture&>(source);
|
||||||
|
|
||||||
|
const GL::Context& context = m_texture.EnsureDeviceContext();
|
||||||
|
|
||||||
|
// Use glCopyImageSubData if available
|
||||||
|
if (context.glCopyImageSubData)
|
||||||
|
{
|
||||||
|
GLuint srcImage = glTexture.GetTexture().GetObjectId();
|
||||||
|
GLenum srcTarget = ToOpenGL(ToTextureTarget(glTexture.GetType()));
|
||||||
|
|
||||||
|
GLuint dstImage = m_texture.GetObjectId();
|
||||||
|
GLenum dstTarget = ToOpenGL(ToTextureTarget(m_params.type));
|
||||||
|
|
||||||
|
context.glCopyImageSubData(srcImage, srcTarget, 0, GLint(srcBox.x), GLint(srcBox.y), GLint(srcBox.z), dstImage, dstTarget, 0, GLint(dstPos.x), GLint(dstPos.y), GLint(dstPos.z), GLsizei(srcBox.width), GLsizei(srcBox.height), GLsizei(srcBox.depth));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//TODO: Blit using framebuffers
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
PixelFormat OpenGLTexture::GetFormat() const
|
PixelFormat OpenGLTexture::GetFormat() const
|
||||||
{
|
{
|
||||||
return m_params.pixelFormat;
|
return m_params.pixelFormat;
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,57 @@ namespace Nz
|
||||||
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
|
vmaDestroyImage(m_device.GetMemoryAllocator(), m_image, m_allocation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VulkanTexture::Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos)
|
||||||
|
{
|
||||||
|
const VulkanTexture& sourceTexture = static_cast<const VulkanTexture&>(source);
|
||||||
|
|
||||||
|
Vk::AutoCommandBuffer copyCommandBuffer = m_device.AllocateCommandBuffer(QueueType::Graphics);
|
||||||
|
if (!copyCommandBuffer->Begin(VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VkImageSubresourceLayers subresourceLayers = { //< FIXME
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
0, //< mipLevel
|
||||||
|
0, //< baseArrayLayer
|
||||||
|
1 //< layerCount
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageSubresourceRange subresourceRange = { //< FIXME
|
||||||
|
VK_IMAGE_ASPECT_COLOR_BIT,
|
||||||
|
0, //< baseMipLevel
|
||||||
|
1, //< levelCount
|
||||||
|
subresourceLayers.baseArrayLayer, //< baseArrayLayer
|
||||||
|
subresourceLayers.layerCount //< layerCount
|
||||||
|
};
|
||||||
|
|
||||||
|
VkImageCopy region = {
|
||||||
|
subresourceLayers,
|
||||||
|
VkOffset3D { static_cast<Int32>(srcBox.x), static_cast<Int32>(srcBox.y), static_cast<Int32>(srcBox.z) },
|
||||||
|
subresourceLayers,
|
||||||
|
VkOffset3D { static_cast<Int32>(dstPos.x), static_cast<Int32>(dstPos.y), static_cast<Int32>(dstPos.z) },
|
||||||
|
VkExtent3D { static_cast<UInt32>(srcBox.width), static_cast<UInt32>(srcBox.height), static_cast<UInt32>(srcBox.depth) }
|
||||||
|
};
|
||||||
|
|
||||||
|
copyCommandBuffer->SetImageLayout(sourceTexture.GetImage(), VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresourceRange);
|
||||||
|
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresourceRange);
|
||||||
|
|
||||||
|
copyCommandBuffer->CopyImage(sourceTexture.GetImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, region);
|
||||||
|
|
||||||
|
copyCommandBuffer->SetImageLayout(sourceTexture.GetImage(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresourceRange);
|
||||||
|
copyCommandBuffer->SetImageLayout(m_image, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, subresourceRange);
|
||||||
|
|
||||||
|
if (!copyCommandBuffer->End())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Vk::QueueHandle transferQueue = m_device.GetQueue(m_device.GetDefaultFamilyIndex(QueueType::Graphics), 0);
|
||||||
|
if (!transferQueue.Submit(copyCommandBuffer))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
transferQueue.WaitIdle();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
PixelFormat VulkanTexture::GetFormat() const
|
PixelFormat VulkanTexture::GetFormat() const
|
||||||
{
|
{
|
||||||
return m_params.pixelFormat;
|
return m_params.pixelFormat;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue