Skip to content

Commit

Permalink
No need to create an intermediate buffer as the ConvertImageBuffer fu…
Browse files Browse the repository at this point in the history
…nction support rowStride now
  • Loading branch information
st0rmbtw committed Jan 27, 2025
1 parent 6396308 commit 9caeb59
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 78 deletions.
19 changes: 3 additions & 16 deletions sources/Renderer/Direct3D11/Texture/D3D11Texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,27 +297,14 @@ HRESULT D3D11Texture::UpdateSubresource(
const char* srcData = static_cast<const char*>(imageView.data);
LLGL_ASSERT_PTR(srcData);

const std::size_t srcBytesPerPixel = GetMemoryFootprint(imageView.format, imageView.dataType, 1);
std::uint32_t srcRowStride = (imageView.rowStride > 0 ? imageView.rowStride : extent.width) * srcBytesPerPixel;
std::uint32_t srcLayerStride = (extent.height * srcRowStride);
std::uint32_t srcRowStride = imageView.rowStride > 0 ? imageView.rowStride : dataLayout.rowStride;
std::uint32_t srcLayerStride = imageView.rowStride > 0 ? imageView.rowStride * extent.height : dataLayout.layerStride;

if ((formatAttribs.flags & FormatFlags::IsCompressed) == 0 &&
(formatAttribs.format != imageView.format || formatAttribs.dataType != imageView.dataType))
{
const std::uint32_t dstRowStride = extent.width * srcBytesPerPixel;
const std::uint32_t dstLayerStride = extent.height * dstRowStride;

if (srcRowStride != dstRowStride)
{
intermediateData = DynamicByteArray{ imageView.dataSize, UninitializeTag{} };
CopyRowAlignedData(intermediateData.get(), imageView.dataSize, dstRowStride, srcData, srcRowStride);
srcData = intermediateData.get();
}

const ImageView srcImageView{ imageView.format, imageView.dataType, srcData, imageView.dataSize, imageView.rowStride };

/* Convert image data (e.g. from RGB to RGBA), and redirect initial data to new buffer */
intermediateData = ConvertImageBuffer(srcImageView, formatAttribs.format, formatAttribs.dataType, LLGL_MAX_THREAD_COUNT);
intermediateData = ConvertImageBuffer(imageView, formatAttribs.format, formatAttribs.dataType, extent, LLGL_MAX_THREAD_COUNT);
srcData = intermediateData.get();
srcRowStride = dataLayout.rowStride;
srcLayerStride = dataLayout.layerStride;
Expand Down
19 changes: 3 additions & 16 deletions sources/Renderer/Direct3D12/D3D12RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -867,27 +867,14 @@ HRESULT D3D12RenderSystem::UpdateTextureSubresourceFromImage(
DynamicByteArray intermediateData;
const void* srcData = imageView.data;

const std::size_t srcBytesPerPixel = GetMemoryFootprint(imageView.format, imageView.dataType, 1);
std::uint32_t srcRowStride = (imageView.rowStride > 0 ? imageView.rowStride : region.extent.width) * srcBytesPerPixel;
std::uint32_t srcLayerStride = (region.extent.height * srcRowStride);
std::uint32_t srcRowStride = imageView.rowStride > 0 ? imageView.rowStride : dataLayout.rowStride;
std::uint32_t srcLayerStride = imageView.rowStride > 0 ? imageView.rowStride * region.extent.height : dataLayout.layerStride;

if ((formatAttribs.flags & FormatFlags::IsCompressed) == 0 &&
(formatAttribs.format != imageView.format || formatAttribs.dataType != imageView.dataType))
{
const std::uint32_t dstRowStride = region.extent.width * srcBytesPerPixel;
const std::uint32_t dstLayerStride = region.extent.height * dstRowStride;

if (srcRowStride != dstRowStride)
{
intermediateData = DynamicByteArray{ imageView.dataSize, UninitializeTag{} };
CopyRowAlignedData(intermediateData.get(), imageView.dataSize, dstRowStride, srcData, srcRowStride);
srcData = intermediateData.get();
}

const ImageView srcImageView{ imageView.format, imageView.dataType, srcData, imageView.dataSize, imageView.rowStride };

/* Convert image data (e.g. from RGB to RGBA), and redirect initial data to new buffer */
intermediateData = ConvertImageBuffer(srcImageView, formatAttribs.format, formatAttribs.dataType, LLGL_MAX_THREAD_COUNT);
intermediateData = ConvertImageBuffer(imageView, formatAttribs.format, formatAttribs.dataType, region.extent, LLGL_MAX_THREAD_COUNT);
srcData = intermediateData.get();
srcRowStride = dataLayout.rowStride;
srcLayerStride = dataLayout.layerStride;
Expand Down
14 changes: 14 additions & 0 deletions sources/Renderer/RenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,20 @@ void RenderSystem::AssertImageDataSize(std::size_t dataSize, std::size_t require
);
}

static void CopyRowAlignedData(void* dstData, std::size_t dstSize, std::size_t dstStride, const void* srcData, std::size_t srcStride)
{
LLGL_ASSERT_PTR(dstData);
LLGL_ASSERT_PTR(srcData);
LLGL_ASSERT(dstStride > 0);
LLGL_ASSERT(dstStride <= srcStride, "dstStride (%u) is not less than or equal to srcStride (%u)", dstStride, srcStride);

auto dst = static_cast<char*>(dstData);
auto src = static_cast<const char*>(srcData);

for (char* dstEnd = dst + dstSize; dst < dstEnd; dst += dstStride, src += srcStride)
::memcpy(dst, src, dstStride);
}

std::size_t RenderSystem::CopyTextureImageData(
const MutableImageView& dstImageView,
const ImageView& srcImageView,
Expand Down
12 changes: 0 additions & 12 deletions sources/Renderer/TextureUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,7 @@ LLGL_EXPORT int CompareCompressedTexViewSWO(const CompressedTexView& lhs, const
return std::memcmp(&lhs, &rhs, sizeof(CompressedTexView));
}

LLGL_EXPORT void CopyRowAlignedData(void* dstData, std::size_t dstSize, std::size_t dstStride, const void* srcData, std::size_t srcStride)
{
LLGL_ASSERT_PTR(dstData);
LLGL_ASSERT_PTR(srcData);
LLGL_ASSERT(dstStride > 0);
LLGL_ASSERT(dstStride <= srcStride, "dstStride (%u) is not less than or equal to srcStride (%u)", dstStride, srcStride);

auto dst = static_cast<char*>(dstData);
auto src = static_cast<const char*>(srcData);

for (char* dstEnd = dst + dstSize; dst < dstEnd; dst += dstStride, src += srcStride)
::memcpy(dst, src, dstStride);
}

} // /namespace LLGL

Expand Down
1 change: 0 additions & 1 deletion sources/Renderer/TextureUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ inline bool IsTextureViewEnabled(const TextureViewDescriptor& textureViewDesc)
);
}

LLGL_EXPORT void CopyRowAlignedData(void* dstData, std::size_t dstSize, std::size_t dstStride, const void* srcData, std::size_t srcStride);


} // /namespace LLGL
Expand Down
39 changes: 6 additions & 33 deletions sources/Renderer/Vulkan/VKRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,42 +304,29 @@ Texture* VKRenderSystem::CreateTexture(const TextureDescriptor& textureDesc, con
const std::size_t initialDataSize = GetMemoryFootprint(textureDesc.format, imageSize);
const std::size_t bytesPerPixel = GetMemoryFootprint(textureDesc.format, 1);
const auto& formatAttribs = GetFormatAttribs(textureDesc.format);
const Extent3D& extent = textureDesc.extent;

/* Set up initial image data */
const void* initialData = nullptr;
DynamicByteArray intermediateData;

std::size_t srcRowStride = textureDesc.extent.width * bytesPerPixel;
std::size_t srcRowStride = extent.width * bytesPerPixel;

if (initialImage != nullptr)
{
const ImageView& srcImageView = *initialImage;
const Extent3D& extent = textureDesc.extent;

const void* srcData = initialImage->data;

const std::uint32_t srcBytesPerPixel = GetMemoryFootprint(srcImageView.format, srcImageView.dataType, 1);
srcRowStride = (srcImageView.rowStride > 0 ? srcImageView.rowStride : extent.width) * srcBytesPerPixel;
srcRowStride = srcImageView.rowStride > 0 ? srcImageView.rowStride : extent.width * srcBytesPerPixel;

/* Check if image data must be converted */
if ((formatAttribs.flags & FormatFlags::IsCompressed) == 0 &&
(formatAttribs.format != srcImageView.format || formatAttribs.dataType != srcImageView.dataType))
{
const std::size_t dstRowStride = extent.width * srcBytesPerPixel;
const std::size_t dstLayerStride = extent.height * dstRowStride;
const void* srcData = srcImageView.data;

if (srcRowStride != dstRowStride)
{
intermediateData = DynamicByteArray{ srcImageView.dataSize, UninitializeTag{} };
CopyRowAlignedData(intermediateData.get(), srcImageView.dataSize, dstRowStride, srcData, srcRowStride);
srcData = intermediateData.get();
}

const ImageView imageView{ srcImageView.format, srcImageView.dataType, srcData, srcImageView.dataSize, srcImageView.rowStride };

/* Convert image format (will be null if no conversion is necessary) */
intermediateData = ConvertImageBuffer(imageView, formatAttribs.format, formatAttribs.dataType, LLGL_MAX_THREAD_COUNT);
intermediateData = ConvertImageBuffer(srcImageView, formatAttribs.format, formatAttribs.dataType, extent, LLGL_MAX_THREAD_COUNT);
srcRowStride = extent.width * bytesPerPixel;
}

Expand Down Expand Up @@ -473,28 +460,14 @@ void VKRenderSystem::WriteTexture(Texture& texture, const TextureRegion& texture
/* Check if image data must be converted */
DynamicByteArray intermediateData;

const std::uint32_t srcBytesPerPixel = GetMemoryFootprint(srcImageView.format, srcImageView.dataType, 1);
std::size_t srcRowStride = (srcImageView.rowStride > 0 ? srcImageView.rowStride : extent.width) * srcBytesPerPixel;
std::uint32_t srcRowStride = srcImageView.rowStride > 0 ? srcImageView.rowStride : extent.width * bytesPerPixel;

const auto& formatAttribs = GetFormatAttribs(format);
if ((formatAttribs.flags & FormatFlags::IsCompressed) == 0 &&
(formatAttribs.format != srcImageView.format || formatAttribs.dataType != srcImageView.dataType))
{
const std::size_t dstRowStride = extent.width * srcBytesPerPixel;
const std::size_t dstLayerStride = extent.height * dstRowStride;
const void* srcData = srcImageView.data;

if (srcRowStride != dstRowStride)
{
intermediateData = DynamicByteArray{ srcImageView.dataSize, UninitializeTag{} };
CopyRowAlignedData(intermediateData.get(), srcImageView.dataSize, dstRowStride, srcData, srcRowStride);
srcData = intermediateData.get();
}

const ImageView imageView{ srcImageView.format, srcImageView.dataType, srcData, srcImageView.dataSize, srcImageView.rowStride };

/* Convert image format (will be null if no conversion is necessary) */
intermediateData = ConvertImageBuffer(imageView, formatAttribs.format, formatAttribs.dataType, LLGL_MAX_THREAD_COUNT);
intermediateData = ConvertImageBuffer(srcImageView, formatAttribs.format, formatAttribs.dataType, extent, LLGL_MAX_THREAD_COUNT);
srcRowStride = extent.width * bytesPerPixel;
}

Expand Down

0 comments on commit 9caeb59

Please sign in to comment.