diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index dab6bd90b..825840a6f 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -2835,7 +2835,20 @@ namespace bgfx { namespace mtl void TextureMtl::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem) { const uint32_t bpp = bimg::getBitsPerPixel(bimg::TextureFormat::Enum(m_textureFormat) ); - const uint32_t rectpitch = _rect.m_width*bpp/8; + uint32_t rectpitch = _rect.m_width*bpp/8; + if (bimg::isCompressed(bimg::TextureFormat::Enum(m_textureFormat))) + { + if (m_ptr.pixelFormat() >= 160 /*PVRTC_RGB_2BPP*/ + && m_ptr.pixelFormat() <= 167 /*PVRTC_RGBA_4BPP_sRGB*/) + { + rectpitch = 0; + } + else + { + const bimg::ImageBlockInfo& blockInfo = bimg::getBlockInfo(bimg::TextureFormat::Enum(m_textureFormat)); + rectpitch = (_rect.m_width / blockInfo.blockWidth)*blockInfo.blockSize; + } + } const uint32_t srcpitch = UINT16_MAX == _pitch ? rectpitch : _pitch; const uint32_t slice = ( (m_type == Texture3D) ? 0 : _side + _z * (m_type == TextureCube ? 6 : 1) ); const uint16_t zz = (m_type == Texture3D) ? _z : 0 ; @@ -2876,30 +2889,35 @@ namespace bgfx { namespace mtl { BlitCommandEncoder bce = s_renderMtl->getBlitCommandEncoder(); - const uint32_t dstpitch = bx::strideAlign(rectpitch, 64); - - Buffer tempBuffer = s_renderMtl->m_device.newBufferWithLength(dstpitch*_rect.m_height, 0); - - const uint8_t* src = (uint8_t*)data; - uint8_t* dst = (uint8_t*)tempBuffer.contents(); - - for (uint32_t yy = 0; yy < _rect.m_height; ++yy, src += srcpitch, dst += dstpitch) + TextureDescriptor desc = s_renderMtl->m_textureDescriptor; + desc.textureType = _depth > 1 ? MTLTextureType3D : MTLTextureType2D; + desc.pixelFormat = m_ptr.pixelFormat(); + desc.width = _rect.m_width; + desc.height = _rect.m_height; + desc.depth = _depth; + desc.mipmapLevelCount = 1; + desc.sampleCount = 1; + desc.arrayLength = 1; + if (s_renderMtl->m_iOS9Runtime + || s_renderMtl->m_macOS11Runtime) { - bx::memCopy(dst, src, rectpitch); + desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; + desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) + ? (MTLStorageMode)0 // MTLStorageModeShared + : (MTLStorageMode)1 // MTLStorageModeManaged + ; + desc.usage = 0; } - - bce.copyFromBuffer( - tempBuffer - , 0 - , dstpitch - , dstpitch * _rect.m_height - , MTLSizeMake(_rect.m_width, _rect.m_height, _depth) - , m_ptr - , slice - , _mip - , MTLOriginMake(_rect.m_x, _rect.m_y, zz) - ); - release(tempBuffer); + Texture tempTexture = s_renderMtl->m_device.newTextureWithDescriptor(desc); + MTLRegion region = + { + { 0, 0, 0 }, + { _rect.m_width, _rect.m_height, _depth }, + }; + tempTexture.replaceRegion(region, 0, 0, data, srcpitch, srcpitch * _rect.m_height); + bce.copyFromTexture(tempTexture, 0, 0, MTLOriginMake(0,0,0), MTLSizeMake(_rect.m_width, _rect.m_height, _depth), + m_ptr, slice, _mip, MTLOriginMake(_rect.m_x, _rect.m_y, zz)); + release(tempTexture); } if (NULL != temp)