Skip to content

Commit

Permalink
[Metal] Updated MTTexture implementation to use new ConvertImageBuffe…
Browse files Browse the repository at this point in the history
…r() functionality.

This also fixes "TextureStrides" unit test for Metal.
  • Loading branch information
LukasBanana committed Feb 15, 2025
1 parent 804a538 commit b74a9e2
Showing 1 changed file with 26 additions and 22 deletions.
48 changes: 26 additions & 22 deletions sources/Renderer/Metal/Texture/MTTexture.mm
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ static void ConvertTextureDesc(id<MTLDevice> device, MTLTextureDescriptor* dst,
if (formatAttribs.bitSize > 0 && (formatAttribs.flags & FormatFlags::IsCompressed) == 0)
{
/* Convert image format (will be null if no conversion is necessary) */
intermediateData = ConvertImageBuffer(srcImageView, formatAttribs.format, formatAttribs.dataType, /*cfg.threadCount*/0);
intermediateData = ConvertImageBuffer(srcImageView, formatAttribs.format, formatAttribs.dataType, textureRegion.extent, LLGL_MAX_THREAD_COUNT);
if (intermediateData)
{
/* User converted temporary buffer as image source */
Expand Down Expand Up @@ -318,13 +318,20 @@ static void ConvertTextureDesc(id<MTLDevice> device, MTLTextureDescriptor* dst,
const SubresourceCPUMappingLayout& layout,
const MutableImageView& dstImageView)
{
if (formatAttribs.format != dstImageView.format || formatAttribs.dataType != dstImageView.dataType)
char* dstImageData = static_cast<char*>(dstImageView.data);
std::size_t dstImageDataSize = dstImageView.dataSize;
const std::size_t dstImageLayerStride = GetMemoryFootprint(dstImageView.format, dstImageView.dataType, layout.numTexelsPerLayer);

if (formatAttribs.format != dstImageView.format ||
formatAttribs.dataType != dstImageView.dataType)
{
/* Generate intermediate buffer for conversion */
DynamicByteArray intermediateData = DynamicByteArray{ layout.subresourceSize, UninitializeTag{} };

for_range(arrayLayer, subresource.numArrayLayers)
{
LLGL_ASSERT(dstImageDataSize >= dstImageLayerStride);

/* Copy bytes into intermediate data, then convert its format */
[native_
getBytes: intermediateData.get()
Expand All @@ -336,22 +343,22 @@ static void ConvertTextureDesc(id<MTLDevice> device, MTLTextureDescriptor* dst,
];

/* Convert intermediate data into requested format */
DynamicByteArray formattedData = ConvertImageBuffer(
ImageView{ formatAttribs.format, formatAttribs.dataType, intermediateData.get(), layout.subresourceSize },
dstImageView.format, dstImageView.dataType, /*GetConfiguration().threadCount*/0
);
const ImageView intermediateImageView{ formatAttribs.format, formatAttribs.dataType, intermediateData.get(), layout.subresourceSize };
const MutableImageView dstImageLayerView{ dstImageView.format, dstImageView.dataType, dstImageData, dstImageDataSize };

/* Copy temporary data into output buffer */
::memcpy(dstImageView.data, formattedData.get(), dstImageView.dataSize);
ConvertImageBuffer(intermediateImageView, dstImageLayerView, LLGL_MAX_THREAD_COUNT, true);

dstImageData += dstImageLayerStride;
dstImageDataSize -= dstImageLayerStride;
}
}
else
{
char* dstImageData = static_cast<char*>(dstImageView.data);

for_range(arrayLayer, subresource.numArrayLayers)
{
/* Copy bytes into intermediate data, then convert its format */
LLGL_ASSERT(dstImageDataSize >= layout.layerStride);

[native_
getBytes: dstImageData
bytesPerRow: layout.rowStride
Expand All @@ -360,7 +367,9 @@ static void ConvertTextureDesc(id<MTLDevice> device, MTLTextureDescriptor* dst,
mipmapLevel: subresource.baseMipLevel
slice: subresource.baseArrayLayer + arrayLayer
];

dstImageData += layout.layerStride;
dstImageDataSize -= layout.layerStride;
}
}
}
Expand Down Expand Up @@ -418,18 +427,13 @@ static void CopyIntermediateBufferToImageBuffer(
DataType srcDataType,
const MutableImageView& dstImageView)
{
if (srcImageFormat != dstImageView.format || srcDataType != dstImageView.dataType)
{
ConvertImageBuffer(
ImageView{ srcImageFormat, srcDataType, srcBuffer.GetBytes(), srcBufferSize },
dstImageView
);
}
else
{
/* Copy bytes from intermediate shared buffer into output CPU buffer */
::memcpy(dstImageView.data, srcBuffer.GetBytes(), dstImageView.dataSize);
}
/* Convert or copy intermediate shared buffer into output CPU buffer */
ConvertImageBuffer(
ImageView{ srcImageFormat, srcDataType, srcBuffer.GetBytes(), srcBufferSize },
dstImageView,
LLGL_MAX_THREAD_COUNT,
true
);
}

void MTTexture::ReadRegionFromPrivateMemory(
Expand Down

0 comments on commit b74a9e2

Please sign in to comment.