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() = default;
|
||||
|
||||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||
|
||||
PixelFormat GetFormat() const override;
|
||||
UInt8 GetLevelCount() 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(glViewport, PFNGLVIEWPORTPROC) \
|
||||
\
|
||||
extCb(glCopyImageSubData, PFNGLCOPYIMAGESUBDATAPROC) \
|
||||
\
|
||||
extCb(glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) \
|
||||
\
|
||||
extCb(glPolygonMode, PFNGLPOLYGONMODEPROC) \
|
||||
|
|
|
|||
|
|
@ -54,6 +54,8 @@ namespace Nz
|
|||
Texture(Texture&&) = delete;
|
||||
virtual ~Texture();
|
||||
|
||||
virtual bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos = Vector3ui::Zero()) = 0;
|
||||
|
||||
virtual PixelFormat GetFormat() const = 0;
|
||||
virtual UInt8 GetLevelCount() const = 0;
|
||||
virtual Vector3ui GetSize(UInt8 level = 0) const = 0;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ namespace Nz
|
|||
VulkanTexture(VulkanTexture&&) = delete;
|
||||
~VulkanTexture();
|
||||
|
||||
bool Copy(const Texture& source, const Boxui& srcBox, const Vector3ui& dstPos) override;
|
||||
|
||||
PixelFormat GetFormat() const override;
|
||||
inline VkImage GetImage() 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, const VkBufferImageCopy& region);
|
||||
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 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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return m_pool->GetDevice()->vkCmdDraw(m_handle, vertexCount, instanceCount, firstVertex, firstInstance);
|
||||
|
|
|
|||
|
|
@ -48,23 +48,14 @@ namespace Nz
|
|||
|
||||
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
|
||||
///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())))
|
||||
if (!newTexture->Copy(oldTexture, Rectui(0, 0, oldSize.x, oldSize.y)))
|
||||
{
|
||||
NazaraError("Failed to update texture");
|
||||
return nullptr;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
return newTexture;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,32 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
return m_params.pixelFormat;
|
||||
|
|
|
|||
|
|
@ -147,6 +147,57 @@ namespace Nz
|
|||
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
|
||||
{
|
||||
return m_params.pixelFormat;
|
||||
|
|
|
|||
Loading…
Reference in New Issue